Day73.SpringMVC案例:影院系统、使用Restful风格重构
目录
springMVC:影院系统
一、准备SpringMVC环境
二、首页显示所有电影
三、影院案例-删除指定电影信息
四、影院案例-添加新电影
五、影院案例-修改指定电影信息
六、总结
七、Restful风格 重构影院系统 ★
一、路径清单
二、准备操作 (配置过滤器)
三、访问首页
四、查询所有 (跳转影院页面)
五、添加操作
六、修改操作 ★
七、删除操作 ★
八、路径冲突问题、总结
springMVC:影院系统
数据库怎么办?使用HashMap模拟。暂时不涉及和MyBatis、Spring的整合,重点就是SpringMVC的使用:先搭建SpringMVC的环境,通过页面、分控制器的操作来说功能。
一、准备SpringMVC环境
1、maven添加依赖
Servlet依赖、SpringMVC依赖、Spring和Thymeleaf的整合依赖、Lombok、日志Logback、Spring Test、Junit5
<dependencies><!-- ServletAPI --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!--SpringMVC--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.1</version></dependency><!-- Spring5和Thymeleaf整合包 --><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring5</artifactId><version>3.0.12.RELEASE</version></dependency><!--logback日志 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!--lombok日志--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!--SpringTest--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.1</version></dependency><!--Junit5--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.7.0</version><scope>test</scope></dependency></dependencies>
2、配置web.xml
SpringMVC总控制器、解决Post请求中文乱码问题
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--中央控制器--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><!--配置文件--><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!--总控制器启动时机,注意必须写--><load-on-startup>1</load-on-startup></servlet><!--Servlet映射路径--><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--解决乱码--><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param><!--强制请求编码--><init-param><param-name>forceRequestEncoding</param-name><param-value>true</param-value></init-param><!--强制响应编码--><init-param><param-name>forceResponseEncoding</param-name><param-value>true</param-value></init-param></filter><!--映射路径--><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>
3、配置 springmvc.xml
组件(@Controller @Service)扫描、Thymeleaf解析器、启用MVC注解驱动、 解决静态资源访问问题
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 组件扫描--><context:component-scan base-package="com.atguigu"></context:component-scan><!-- 启用SpringMVC注解驱动--><mvc:annotation-driven></mvc:annotation-driven><!-- 让静态资源可以正常访问--><mvc:default-servlet-handler></mvc:default-servlet-handler><!-- 配置视图控制器--><!--/,默认访问就是--><mvc:view-controller path="/" view-name="portal"></mvc:view-controller><!-- 配置Thymeleaf视图解析器--><bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="UTF-8"/><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!-- 视图前缀 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 视图后缀 --><property name="suffix" value=".html"/><property name="templateMode" value="HTML5"/><property name="characterEncoding" value="UTF-8" /></bean></property></bean></property></bean>
</beans>
4、日志logback.xml
resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<!-- 指定日志输出的位置 -->
<appender name="STDOUT"class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 日志输出的格式 --><!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 --><pattern>%d{HH:mm:ss.SSS} [%-5level] [%thread] <!--[%logger]--> [%msg]%n</pattern></encoder>
</appender><!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR -->
<!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
<root level="INFO"><!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender --><appender-ref ref="STDOUT" />
</root><!-- 根据特殊需求指定局部日志级别 -->
<logger name="org.springframework.web.servlet.DispatcherServlet" level="DEBUG" />
<logger name="com.atguigu.controller" level="DEBUG" /></configuration>
5、创建目录结构
6、准备实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Movie {private String movieId;private String movieName;private Double moviePrice;
}
7、准备业务层接口和实现类代码(提供模拟数据)
public interface MovieService {List<Movie> getAll();Movie getMovieById(String movieId);void saveMovie(Movie movie);void updateMovie(Movie movie);void removeMovieById(String movieId);
}@Service
public class MovieServiceImpl implements MovieService {private static Map<String , Movie> movieMap;static {movieMap = new HashMap<>();String movieId = null;Movie movie = null;movieId = "M001";movie = new Movie(movieId, "肖申克救赎", 10.0);movieMap.put(movieId, movie);movieId = "M002";movie = new Movie(movieId, "泰坦尼克号", 20.0);movieMap.put(movieId, movie);movieId = "M003";movie = new Movie(movieId, "审死官", 30.0);movieMap.put(movieId, movie);movieId = "M004";movie = new Movie(movieId, "大话西游之大圣娶亲", 40.0);movieMap.put(movieId, movie);movieId = "M005";movie = new Movie(movieId, "大话西游之仙履奇缘", 50.0);movieMap.put(movieId, movie);movieId = "M006";movie = new Movie(movieId, "功夫", 60.0);movieMap.put(movieId, movie);movieId = "M007";movie = new Movie(movieId, "大内密探凌凌漆", 70.0);movieMap.put(movieId, movie);movieId = "M008";movie = new Movie(movieId, "食神", 80.0);movieMap.put(movieId, movie);movieId = "M009";movie = new Movie(movieId, "西游降魔篇", 90.0);movieMap.put(movieId, movie);movieId = "M010";movie = new Movie(movieId, "西游伏妖篇", 11.0);movieMap.put(movieId, movie);movieId = "M011";movie = new Movie(movieId, "三傻大闹宝莱坞", 12.0);movieMap.put(movieId, movie);movieId = "M012";movie = new Movie(movieId, "唐人街探案", 13.0);movieMap.put(movieId, movie);movieId = "M013";movie = new Movie(movieId, "一个人的武林", 14.0);movieMap.put(movieId, movie);movieId = "M014";movie = new Movie(movieId, "罗马假日", 15.0);movieMap.put(movieId, movie);movieId = "M015";movie = new Movie(movieId, "花季雨季", 16.0);movieMap.put(movieId, movie);movieId = "M016";movie = new Movie(movieId, "夏洛特烦恼", 17.0);movieMap.put(movieId, movie);}@Overridepublic List<Movie> getAll() {return new ArrayList<>(movieMap.values());}@Overridepublic Movie getMovieById(String movieId) {return movieMap.get(movieId);}@Overridepublic void saveMovie(Movie movie) {//String movieId = UUID.randomUUID().toString().replace("-", "");//movie.setMovieId(movieId);movieMap.put(movie.getMovieId(), movie);}@Overridepublic void updateMovie(Movie movie) {String movieId = movie.getMovieId();movieMap.put(movieId, movie);}@Overridepublic void removeMovieById(String movieId) {movieMap.remove(movieId);}
}
8、测试业务层代码
//JUint5
@SpringJUnitConfig(locations = "classpath:springmvc.xml")
//@ExtendWith(SpringExtension.class)
//@ContextConfiguration(locations = "classpath:springmvc.xml")
public class TestMovie {@Autowiredprivate MovieService movieService;@Testpublic void testGetAll(){List<Movie> movieList = movieService.getAll();movieList.forEach(movie -> System.out.println(movie));}@Testpublic void testGetMovieById(){Movie movie = movieService.getMovieById("M005");System.out.println(movie);}@Testpublic void testSaveMovie(){Movie movie = new Movie("M022","长津湖",67.0);movieService.saveMovie(movie);List<Movie> movieList = movieService.getAll();movieList.forEach(movie1 -> System.out.println(movie1));}
}
9、首页显示
springmvc.xml
<!-- 配置视图控制器-->
<mvc:view-controller path="/" view-name="portal"></mvc:view-controller>
<body><a th:href="@{/movie/getAll}">进入影院系统</a>
</body>
二、首页显示所有电影
@Controller//控制层,声明分控制器
@Slf4j
@RequestMapping("/movie")
public class MovieController {//自动匹配,业务逻辑层@Autowiredprivate MovieService movieService;@RequestMapping("/getAll")public String getAll(Model model){List<Movie> movieList = movieService.getAll();model.addAttribute("movieList",movieList);return "movieList";}}
<body>
<h3>电影列表</h3>
<table id="table1"><tr><th>电影编号</th><th>电影名称</th><th>观赏价格</th><th>status.even</th><th>status.index</th><th>操作</th></tr><!--如果没有电影--><tbody th:if="${movieList==null or movieList.size==0}"><tr><td colspan="11">一部电影也没有</td></tr></tbody><tbody th:if="${not #lists.isEmpty(movieList)}"><tr th:each="movie,status:${movieList}" th:class="${status.even?'white':'beige'}"><!--status:风格--><td th:text="${movie.movieId}"></td><td th:text="${movie.movieName}"></td><td th:text="${movie.moviePrice}"></td><td th:text="${status.even}"></td><td th:text="${status.index}"></td><td>操作</td></tr></tbody>
</table>
</body>
<!--风格--><style type="text/css">h3{text-align: center;}table#table1{width: 60%;margin: 10px auto;border-collapse: collapse;}table#table1 th, td{text-align: center;border:1px solid black;}.white{background-color: wheat;background-color: beige;}</style>
三、影院案例-删除指定电影信息
注意:return时,如果要跳转到分控制器的方法,而不是页面,必须要添加forward或者redirect
<td><a th:href="@{/movie/getMovieById(movieId=${movie.movieId})}">修改</a><a th:href="@{/movie/removeMovieById(movieId=${movie.movieId})}">只是删除</a><a href="javascript:void(0)" th:onclick="confirmRemove([[${movie.movieId}]])">删除+确认</a>
</td><script type="text/javascript">function confirmRemove(movieId){var flag = window.confirm("您确认要删除该电影信息吗");if(flag){location.href="/day10moviemgr/movie/removeMovieById?movieId="+movieId}}
</script>
@RequestMapping("/removeMovieById")public String removeMovieById(String movieId){this.movieService.removeMovieById(movieId);//return "movieList"; 不可以直接跳到movieList页面,没有经过查询没有数据//return "getAll"; 不可以直接写getA,会当做一个页面//return "forword:/movie/getAll"; //对于DML不建议这么来写,尤其是insert,导致表单重复提交return "redirect:/movie/getAll";}
四、影院案例-添加新电影
跳转到添加页面、提交表单保存电影。
注意:如果使用请求转发,是跳转前的地址,会导致表单重复提交;重定向的地址,是跳转后的地址,不会导致表单重复提交
<td colspan="11"><a th:href="@{/movie/toAdd}">添加一部电影</a>
</td>
<!--视图控制器-->
<mvc:view-controller path="/movie/toAdd" view-name="movieAdd"></mvc:view-controller>
movieAdd.html
<body>
<h1>添加电影信息</h1>
<form th:action="@{/movie/addMovie}" method="post">电影编号:<input type="text" name="movieId"><br/>电影名称:<input type="text" name="movieName" /><br/>电影票价格:<input type="text" name="moviePrice" /><br/><button type="submit">保存</button>
</form>
</body>
@RequestMapping("/addMovie")public String addMovie(Movie movie){this.movieService.saveMovie(movie);return "redirect:/movie/getAll";}
五、影院案例-修改指定电影信息
通过查询,将数据回显到更新页面,更新提交表单,接收数据进行修改
<td><a th:href="@{/movie/getMovieById(movieId=${movie.movieId})}">修改</a>
<td/>
@RequestMapping("/getMovieById")public String getMovieById(String movieId,Model model){Movie movie = this.movieService.getMovieById(movieId);model.addAttribute("movie",movie);return "movieUpdate";}
<h1>修改电影信息</h1>
<form th:action="@{/movie/updateMovie}" method="post">电影编号:<input type="text" name="movieId" th:value="${movie.movieId}" readonly><br/>电影名称:<input type="text" name="movieName" th:value="${movie.movieName}"/><br/>电影票价格:<input type="text" name="moviePrice" th:value="${movie.moviePrice}"/><br/><button type="submit">保存</button></form>
@RequestMapping("/updateMovie")public String updateMovie(Movie movie){this.movieService.updateMovie(movie);return "redirect:/movie/getAll";}
六、总结
判断集合内容是否为空
<tbody th:if="${movieList==null or movieList.size==0}"> |
<tbody th:if="${not #lists.isEmpty(movieList)}"> |
如何遍历List
<tr th:each="movie,status:${movieList}" > |
实现隔行变色
.white{ |
<tr th:each="movie,status:${movieList}" th:class="${status.even?'white':'beige'}"> |
修改和删除的超链接,如何传递参数
<a th:href="@{/movie/getMovieById(movieId=${movie.movieId})}">修改</a> |
表单数据回显
<h3>修改电影信息</h3> |
分控制器
如何接收客户端的参数:传递基本参数和实体类
@RequestMapping("/removeMovieById") } |
@RequestMapping("/addMovie") } |
如何传递参数给下一个组件,多种方式,此处采用Model传递,底层将数据保存在request域。
@RequestMapping("/getAll") |
DML操作后如何跳转
- 不能直接跳转到页面来显示,应该先查询再显示
- 处理完后建议使用redirect而不是forward进行跳转,避免表单的重复提交。
@RequestMapping("/removeMovieById") |
七、Restful风格 重构影院系统 ★
一、路径清单
功能 | URL 地址 | 请求方式 |
---|---|---|
访问首页√ | / | GET |
查询全部数据√ | /movie | GET |
删除√ | /movie/M001 | DELETE |
跳转到添加数据的表单√ | /movie/toAdd (伏笔) | GET |
执行保存√ | /movie | POST |
跳转到更新数据的表单√ | /movie/M001 (伏笔) | GET |
执行更新√ | /movie | PUT |
二、准备操作 (配置过滤器)
<!-- 配置将Post请求转换为put、delete请求的过滤器-->
<filter><filter-name>hiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping><filter-name>hiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
三、访问首页
不需要修改
<mvc:view-controller path="/" view-name="portal"></mvc:view-controller>
四、查询所有 (跳转影院页面)
<body><a th:href="@{/movie}">进入电影信息列表</a>
</body>
@Controller
@RequestMapping("/movie")
public class MovieController {@Autowiredprivate MovieService movieService;//查询所有,将信息加入请求域@GetMappingpublic String getAll(Model model){List<Movie> movieList = this.movieService.getAll();model.addAttribute("movieList",movieList);return "movieList";}
五、添加操作
1.跳转到添加页面,无需修改
<mvc:view-controller path="/movie/page/toAdd" view-name="movieAdd"></mvc:view-controller>
2.添加操作
<h1>添加电影信息</h1>
<form th:action="@{/movie}" method="post">电影编号:<input type="text" name="movieId"><br/>电影名称:<input type="text" name="movieName" /><br/>电影票价格:<input type="text" name="moviePrice" /><br/><button type="submit">保存</button>
</form>
//添加@PostMapping//类上已经声明("/movie"),可以省略public String addMovie(Movie movie){this.movieService.saveMovie(movie);return "redirect:/movie"; //注意此处跳转,已经发生改变。//底层请求转发,请求转发默认为get请求}
六、修改操作 ★
1.查询指定的电影信息,回显到修改页面
<a th:href="@{|/movie/${movie.movieId}|}">修改1</a>
<a th:href="@{/movie/}+${movie.movieId}">修改2</a>
//前往更改页面@GetMapping("/{movieId}")//获取形参,进行映射public String getMovieById(@PathVariable("movieId")String movieId,Model model){Movie movie = this.movieService.getMovieById(movieId);model.addAttribute("movie",movie);return "movieUpdate";}
2.修改电影信息
<h1>修改电影信息</h1>
<form th:action="@{/movie}" method="post"><!--复合请求--><input type="hidden" name="_method" value="put">电影编号:<input type="text" name="movieId" th:value="${movie.movieId}" readonly><br/>电影名称:<input type="text" name="movieName" th:value="${movie.movieName}"/><br/>电影票价格:<input type="text" name="moviePrice" th:value="${movie.moviePrice}"/><br/><button type="submit">保存</button>
</form>
//修改@PutMappingpublic String updateMovie(Movie movie){this.movieService.updateMovie(movie);return "redirect:/movie";}
七、删除操作 ★
需要使用vue,通过单击事件,在一个表单中进行请求类型转换
1.页面构建vue,点击事件绑定
//引入vue<!--<base th:href="@{/}"><script src="js/vue.js"></script>--><script th:src="@{/js/vue.js}"></script>
<a th:href="@{|/movie/${movie.movieId}|}" @click.prevent="removeMovie">删除</a>
<a th:href="@{|/movie/${movie.movieId}|}" @click.prevent="confirmRemove">确认删除</a>
2.临时表单 (重要)
将当前超链接的 href 属性赋值给表单的action属性,表单添加_method标签进行请求类型转换,然后在vue事件内进行提交。
<form id="form1" action="" method="post"><input type="hidden" name="_method" value="delete">
</form>
3.vue 代码
<script>new Vue({el:"#tbody1",data:{},methods:{removeMovie:function (){//获取当前事件源的href属性值var href = event.target.href;//将当前href的属性值赋值给表单form1的actiondocument.getElementById("form1").action=href;//提交表单form1document.getElementById("form1").submit();//取消当前a标签默认行为链接跳转//event.preventDefault();},confirmRemove:function (movieId){var flag = window.confirm("您确认要删除该电影信息吗");if(flag){//获取当前事件源的href属性值var href = event.target.href;//将当前href的属性值赋值给表单form1的actiondocument.getElementById("form1").action=href;//提交表单form1document.getElementById("form1").submit();//取消当前a标签默认行为链接跳转//event.preventDefault();}}}})
</script>
4. Controller控制层
@DeleteMapping("/{movieId}")public String removeMovieById(@PathVariable("movieId")String movieId){movieService.removeMovieById(movieId);return "redirect:/movie";}
八、路径冲突问题、总结
点击“添加电影信息”,调用了分控制器的findById(),然后跳转到了修改页面。
原因:两个操作的请求路径相同,参数相同,请求类型都为Get。
SpringMVC会将toAdd理解为一个电影的编号()。
解决:增加层次
<!-- 配置视图控制器-->
<mvc:view-controller path="/movie/page/toAddMovie" view-name="movieAdd"></mvc:view-controller>
<a th:href="@{/movie/page/toAddMovie}">添加电影</a> <!--解决冲突,添加层次-->
总结:使用Restful风格重构项目:
- 修改页面路径
- 修改分控制器的RequestMapping
- 使用@PathVariable指定对应关系
- 页面跳转到分控制器方法是注意路径。
Day73.SpringMVC案例:影院系统、使用Restful风格重构相关推荐
- restful get不传参数404_你知道什么是 Restful 风格吗?SpringMVC 带我们实现它!
Restful 风格的 API 是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓 ...
- RESTful 风格(详细介绍 + 案例实现)
这里写目录标题 RESTful 入门 一.什么是 API(应用程序接口) 二.传统模式和前后端分离模式对比 1. 传统开发模式 2. 前后端分离模式 三.RESTful 风格 1. 概念 2. 资源 ...
- SpringMVC(三)Restful风格及实例、参数的转换
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.Restful风格 1.Restful风格的介绍 Restful 一种软件架构风格.设计风格,而不是 ...
- RESTful风格及其SpringMVC实现
目录 1.RESTful概念 2.RESTful功能 3.对比:传统方式操作资源 4.SpringMVC实现传统方式操作资源 5.使用RestFul操作资源 6.SpringMVC实现RESTful操 ...
- SpringMVC响应Restful风格请求404
一.问题 在学习Springmvc时,使用Restful风格的url,页面提示404错误.为找到原因,编写一个简单的Restful测试用例如下: jsp页面: <a href="use ...
- restful风格案例
RestFul风格案例 理解 一.原则:通过四种不同的请求方式来表示CRUD操作 问题:页面请求只支持get/post方式,并不支持其他方式,如何处理? 二.实际操作时代码 1.html 2.hand ...
- springMVC获取异步请求的参数,返回异步请求数据(json),跨域访问简单了解,文件上传,与Restful风格
springMVC获取异步请求的参数 JQuery发送异步请求回顾 <a href="javascript:void(0);" id="testAjax" ...
- SpringMVC的请求-获得请求参数-Restful风格的参数的获取
Restful是一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等. Res ...
- SpringBoot2.0基础案例(01):环境搭建和RestFul风格接口
一.SpringBoot 框架的特点 SpringBoot2.0 特点 1)SpringBoot继承了Spring优秀的基因,上手难度小 2)简化配置,提供各种默认配置来简化项目配置 3)内嵌式容器简 ...
最新文章
- B2B行业网站编辑轻松创造内容,提高搜索权重
- Android数据存储之SD卡
- 第一次作业(李奇峰 201731062426)
- Windows下 jupyter notebook 运行multiprocessing 报错的问题与解决方法
- 36岁 计算机博士,36岁考博士
- [蓝桥杯2019初赛]不同子串-substr,模拟
- 第四篇:稳定性之提升团队潜意识【及时止损、监控报警】
- 世界地球日:全国网友用手机种出“保护黄河幸福林”
- 已经发车的票还能取出来吗_火车票报销凭证是啥?能不打印吗?官方回应来了...
- 提供两个卡巴斯基的授权文件
- 《系统集成项目管理》第四章 项目管理一般知识
- 学iOS开发需要什么样的基础?
- 基于模板的云服务视频自动生成解决方案
- 微信小程序图片实现宽度100%,高度自适应
- bloomFilter和哈希函数murmur3
- [转]中风后不要贸然放血急救
- myeclipse自定义注释快捷键
- 程序的与时俱进之一——面向接口编程
- TYVJ 01034
- 山东交通学院linux期末考试题,中国近现代史纲要(山东联盟-山东交通学院版)2020知到章节期末答案...