概述
SpringMVC篇
- 2022/8/9 天气:晴天
- SpringMVC
- 1、SpringMVC简介
- 1.1、什么是MVC
- 1.2、什么是SpringMVC
- 1.3、SpringMVC的特点
- 2、入门案例
- 2.1、添加依赖
- 2.2、配置文件
- 2022/8/10 天气:晴天
- 3、@RequestMapping注解
- 3.1、@RequestMapping注解的功能
- 3.2、@RequestMapping注解的位置
- 3.3、@RequestMapping注解的一些属性
- 3.3.1、value
- 3.3.2、method
- 3.3.3、param
- 3.3.4、headers
- 3.5、SpringMVC支持ant风格的路径
- 3.6、SpringMVC支持路径中的占位符
- 2022/8/13 天气:晴天
- 4、SpringMVC获取请求参数
- 4.1、通过ServletAPI获取
- 4.2、通过控制器方法的形参获取
- 4.3、通过pojo获取
- 4.4、处理Tomcat中乱码的问题
- 5、域对象共享数据
- 5.1、使用ServletAPI向request域对象共享数据
- 5.2、使用ModelAndView向request域对象共享数据
- 5.3、使用Model向request域对象共享数据
- 5.4、使用ModelMap向request域对象共享数据
- 5.5、使用Map向request域对象共享数据
- 5.6、向Session域对象共享数据
- 5.7、向Application域对象共享数据
- 2022/8/14 天气:晴天
- 6、SpringMVC的试图
- 6.1、ThymeleafView
- 6.2、转发视图
- 6.3、重定向视图
- 6.4、视图控制器view-controller
- 7、RESTful的案例
- 7.1、RESTful的简介
- 7.2、查询所有员工数据
- 7.3、添加员工信息
- 7.4、修改员工信息
- 7.5、删除员工信息
- 2022/8/15 天气:晴天
- 8、SpringMVC处理ajax请求
- 8.1、@RequestBody
- 8.2、@RequestBody获取json格式的请求参数
- 8.3、@ResponseBody
- 8.4、@ResponseBody响应浏览器json数据
- 8.5、@RestController注解
- 9、文件的上传和下载
- 9.1、文件下载
- 9.2、文件上传
- 2022/8/16 天气:晴天
- 10、拦截器
- 11、异常处理器
- 12、注解配置SpringMVC
- 2022/8/17 天气:雨天
- 13、SpringMVC的执行流程
- 14、SSM的整合
- 1、首先先创建一个maven工程
- 2、添加依赖
- web.xml
- springmvc.xml
- spring.xml
- mybatis-config.xml
- 其他的一些配置
- 4、测试分页功能
- ❀SSM完结撒花❀
2022/8/9 天气:晴天
这周就比较忙哈,主要有朋友来找我玩了,所以就会学的很慢,直接摆一周也不行吧。毕竟还是得看教程,看代码的。
SpringMVC
1、SpringMVC简介
1.1、什么是MVC
M:Model模型 指两类,一类是实体bean对象,一类是业务处理bean对象
V:View,一般指页面,与用户进行交互的界面
C:Controller,控制层,用来接受请求和响应服务器
工作流程:V–>C–>M
1.2、什么是SpringMVC
SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案。在表述层框架历经 Strust、
WebWork、Strust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目
表述层开发的首选方案。
Spring的三层架构:表述层(或表示层)、业务逻辑层、数据访问层
表述层表示前台页面和后台servlet
SpringMVC是为表述层开发的,在后续的整合中,我们可以将MyBatis中的对象放进IOC中,例如SQLsession,将一些事务处理放到声明式事务中去
1.3、SpringMVC的特点
- Spring 家族原生产品,与 IOC 容器等基础设施无缝对接
- 基于原生的Servlet,通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理
表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案 - 代码清新简洁,大幅度提升开发效率
- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
- 性能卓著,尤其适合现代大型、超大型互联网项目要求
2、入门案例
2.1、添加依赖
<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
2.2、配置文件
<!-- 配置SpringMVC的前端控制器,对浏览器发送的请求统一进行处理 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
<!-- 通过初始化参数指定SpringMVC配置文件的位置和名称 -->
<init-param>
<!-- contextConfigLocation为固定值 -->
<param-name>contextConfigLocation</param-name>
<!-- 使用classpath:表示从类路径查找配置文件,例如maven工程中的
src/main/resources -->
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!--
作为框架的核心组件,在启动过程中有大量的初始化操作要做
而这些操作放在第一次请求时才执行会严重影响访问速度
因此需要通过此标签将启动控制DispatcherServlet的初始化时间提前到服务器启动时
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!--
设置springMVC的核心控制器所能处理的请求的请求路径
/所匹配的请求可以是/login或.html或.js或.css方式的请求路径
但是/不能匹配.jsp请求路径的请求
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
2022/8/10 天气:晴天
3、@RequestMapping注解
3.1、@RequestMapping注解的功能
@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联
起来,建立映射关系。
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。
3.2、@RequestMapping注解的位置
@RequestMapping标识一个类:设置映射请求的请求路径的初始信息
@RequestMapping标识一个方法:设置映射请求请求路径的具体信息
两个都有相当于是进行字符串拼接
3.3、@RequestMapping注解的一些属性
3.3.1、value
value属性通过请求的请求地址匹配请求映射,是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求,value值必须设置
<a th:href="@{/testRequestMapping}">测试@RequestMapping的value属性--
>/testRequestMapping</a><br>
<a th:href="@{/test}">测试@RequestMapping的value属性-->/test</a><br>
@RequestMapping(
value = {"/testRequestMapping", "/test"}
)
public String testRequestMapping(){
return "success";
}
3.3.2、method
method:过请求的请求方式(get或post)匹配请求映射,是一个RequestMethod类型(枚举类型)的数组,表示该请求映射能够匹配多种请求方式的请求,若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性,则浏览器报错405:Request method ‘POST’ not supported
<a th:href="@{/test}">测试@RequestMapping的value属性-->/test</a><br>
<form th:action="@{/test}" method="post">
<input type="submit">
</form>
@RequestMapping(
value = {"/testRequestMapping", "/test"},
method = {RequestMethod.GET, RequestMethod.POST}
)
public String testRequestMapping(){
return "success";
}
注:
1、对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解
处理get请求的映射–>@GetMapping
处理post请求的映射–>@PostMapping
处理put请求的映射–>@PutMapping
处理delete请求的映射–>@DeleteMapping
2、常用的请求方式有get,post,put,delete
但是目前浏览器只支持get和post,若在form表单提交时,为method设置了其他请求方式的字符串(put或delete),则按照默认的请求方式get处理
若要发送put和delete请求,则需要通过spring提供的过滤器HiddenHttpMethodFilter,在RESTful部分会讲到
3.3.3、param
params属性通过请求的请求参数匹配请求映射
params属性是一个字符串类型的数组,可以通过四种表达式设置请求参数和请求映射的匹配关系
“param”:要求请求映射所匹配的请求必须携带param请求参数
“!param”:要求请求映射所匹配的请求必须不能携带param请求参数
“param=value”:要求请求映射所匹配的请求必须携带param请求参数且param=value
“param!=value”:要求请求映射所匹配的请求必须携带param请求参数但是param!=value
注:
若当前请求满足@RequestMapping注解的value和method属性,但是不满足params属性,此时
页面回报错400:Parameter conditions “username, password!=123456” not met for actual
request parameters: username={admin}, password={123456}
3.3.4、headers
与param类似
headers属性通过请求的请求头信息匹配请求映射
headers属性是一个字符串类型的数组,可以通过四种表达式设置请求头信息和请求映射的匹配关系
“header”:要求请求映射所匹配的请求必须携带header请求头信息
“!header”:要求请求映射所匹配的请求必须不能携带header请求头信息
“header=value”:要求请求映射所匹配的请求必须携带header请求头信息且header=value
“header!=value”:要求请求映射所匹配的请求必须携带header请求头信息且header!=value
若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性,此时页面显示404错误,即资源未找到
3.5、SpringMVC支持ant风格的路径
?:表示任意的单个字符
*:表示任意的0个或多个字符
**:表示任意层数的任意目录
注意:在使用时,只能使用/**/xxx的方式
3.6、SpringMVC支持路径中的占位符
原始方式:/deleteUser?id=1
rest方式:/user/delete/1
SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,在通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参
<a th:href="@{/testRest/1/admin}">测试路径中的占位符-->/testRest</a><br>
@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id") String id, @PathVariable("username")
String username){
System.out.println("id:"+id+",username:"+username);
return "success";
}
//最终输出的内容为-->id:1,username:admin
2022/8/13 天气:晴天
今天主要是学习了如何在SpringMVC中获取请求参数和使用域对象共享数据
4、SpringMVC获取请求参数
主要3种方法
4.1、通过ServletAPI获取
需要在方法中设置HttpServletRequest参数
@RequestMapping("/param/servletAPI")
public String getParamByServletAPI(HttpServletRequest request) {
// HttpSession session = request.getSession();
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username:" + username + "tpassword:" + password);
return "success";
}
4.2、通过控制器方法的形参获取
只需要在控制器方法的形参位置,设置形参,形参的名字与请求参数的名字一致即可
@RequestParam() 指定该参数为注解中value的值 required = true一定要传,不能不传否则报错 设置成false则可以不传 defaultValue属性 设置一个默认值
@RequestHeader:将请求头信息和控制器方法的形参进行绑定
@CookieValue:将cookie数据和控制器方法的形参进行绑定
@RequestMapping("/param")
public String getParam(
@RequestParam("userName") String username, String password,
@RequestHeader("referer") String referer,
@CookieValue("JSESSIONID") String jsessionId
) {
System.out.println("username:" + username + "tpassword:" + password);
return "success";
}
4.3、通过pojo获取
通过控制器方法的实体类类型pojo参数获取请求参数,实体类对象获取参数 前提是名字保持一致
@RequestMapping("/param/pojo")
public String getParamBypojo(User user) {
System.out.println(user);
return "success";
}
4.4、处理Tomcat中乱码的问题
1、使用filter配置 解决POST方法的乱码
<!-- 编码过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</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>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、在tomcat/conf/server.xml中设置编码 解决GET方法的乱码
大概在66行左右 笔者使用的是tomcat9
<Connector port="8080" URLEncoding="UTF-8" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
注:
SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前,否则无效
5、域对象共享数据
5.1、使用ServletAPI向request域对象共享数据
使用servletAPI向request域对象共享数据 setAttribute() 参数中设置一个HttpServletRequest对象即可
5.2、使用ModelAndView向request域对象共享数据
一定要将ModelAndView对象返回
@RequestMapping("/test/mav")
public ModelAndView testModelAndView() {
/**
* ModelAndView包含Model和View的功能
* Model:向请求域中共享数据
* View:设置逻辑视图实现页面跳转
*/
ModelAndView modelAndView = new ModelAndView();
// 向请求域中共享数据
modelAndView.addObject("testRequestScope", "hello,MAV");
// 设置逻辑视图
modelAndView.setViewName("success");
return modelAndView;
}
5.3、使用Model向request域对象共享数据
@RequestMapping("/test/model")
public String testModel(Model model) {
/**
* Model
*/
model.addAttribute("testRequestScope", "hello, Model");
return "success";
}
5.4、使用ModelMap向request域对象共享数据
@RequestMapping("/test/modelMap")
public String testModelMap(ModelMap modelMap) {
/**
* ModelMap
*/
modelMap.addAttribute("testRequestScope", "hello, ModelMap");
return "success";
}
5.5、使用Map向request域对象共享数据
@RequestMapping("/test/map")
public String testMap(Map<String, Object> map) {
/**
* map
*/
map.put("testRequestScope", "hello, Map");
return "success";
}
org.springframework.validation.support.BindingAwareModelMap
上述除了ServletAPI四者的关系
public interface Model
public class BindingAwareModelMap extends ExtendedModelMap
public class ExtendedModelMap extends ModelMap implements Model
public class ModelMap extends LinkedHashMap<String, Object>
双击Shift查看BindingAwareModelMap即可查看源码,发现用的都是这个
5.6、向Session域对象共享数据
使用ServletAPI
@RequestMapping("/test/session")
public String testSession(HttpSession session) {
session.setAttribute("testSessionScope", "hello, session");
return "success";
}
5.7、向Application域对象共享数据
@RequestMapping("/test/application")
public String testApplication(HttpSession session) {
ServletContext servletContext = session.getServletContext();
servletContext.setAttribute("testApplicationScope", "hello, application");
return "success";
}
2022/8/14 天气:晴天
今天早上结束了计网的学习,完结撒花!学了一下午的SpringMVC,今天主要学习了SpringMVC的视图和RESTful的学习
6、SpringMVC的试图
6.1、ThymeleafView
当我们在控制器中编写方法时,是不是只返回了字符串,这个时候看了源码是默认选择了Thymeleaf视图的
@RequestMapping("/test/view/thymeleaf")
public String testThymeleaf() {
return "success";
}
6.2、转发视图
SpringMVC中的默认转发视图是internalResourceView,当我们以"forward:"开头时,才会在源码中执行转发视图的操作,但是是没有经过渲染的,所以用的不多
当控制器方法中所设置的视图名称以"forward:"为前缀时,创建InternalResourceView视图,此时的视
图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"forward:"去掉,剩余部
分作为最终路径通过转发的方式实现跳转
@RequestMapping("/test/view/forward")
public String testInternalResource() {
return "forward:/test/model";
}
6.3、重定向视图
SpringMVC中默认的重定向视图是RedirectView
当控制器方法中所设置的视图名称以"redirect:"为前缀时,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"redirect:"去掉,剩余部分作为最终路径通过重定向的方式实现跳转
@RequestMapping("/test/view/redirect")
public String testRedirect() {
return "redirect:/test/model";
}
6.4、视图控制器view-controller
<!--
<mvc:annotation-driven /> 没有则404报错
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
-->
注:
当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将全部失效,此时需
要在SpringMVC的核心配置文件中设置开启mvc注解驱动的标签:
<mvc:annotation-driven />
7、RESTful的案例
7.1、RESTful的简介
REST:Representational State Transfer,表现层资源状态转移。
即面向资源编程
GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE用来删除资源。
REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。
在使用表单的时候,我们只能使用method=post|get,对吧,所以在使用put和delete方法时,需要使用到隐藏域,我们需要现在web.xml中配置,然后再在html中写form表单的信息
<!-- 设置请求方式的过滤器 HiddenHttpMethodFilter -->
<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>
<form th:action="@{/user}" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="修改用户信息">
</form>
<form th:action="@{/user/5}" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="删除用户信息">
</form>
注:
form表单中的method一定是post
hidden类型的隐藏域的name一定是_method
这样子,我们才能使用put或者delete方法
7.2、查询所有员工数据
首先搭建环境
pojo: employee
private Integer id;
private String lastName;
private String email;
//1 male, 0 female
private Integer gender;
四个属性,自己封装一下
dao: employeeDao
@Repository
public class EmployeeDao {
private static Map<Integer, Employee> employees = null;
static{
employees = new HashMap<Integer, Employee>();
employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1));
employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1));
employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0));
employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0));
employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1));
}
private static Integer initId = 1006;
public void save(Employee employee) {
if(employee.getId() == null) {
employee.setId(initId++);
}
employees.put(employee.getId(), employee);
}
public Collection<Employee> getAll(){
return employees.values();
}
public Employee get(Integer id){
return employees.get(id);
}
public void delete(Integer id){
employees.remove(id);
}
}
控制器方法:
@RequestMapping(value = "/employee",method = RequestMethod.GET)
public ModelAndView getAllEmployee() {
ModelAndView mav = new ModelAndView();
Collection<Employee> allEmployee = employeeDao.getAll();
// 将所有的员工信息在请求域中共享
mav.addObject("allEmployee", allEmployee);
mav.setViewName("employeeList");
return mav;
}
HTML文件:
<div id="app">
<table>
<tr>
<th colspan="5">employee list</th>
</tr>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>options(<a th:href="@{/to/add}">add</a>)</th>
</tr>
<tr th:each="employee : ${allEmployee}">
<td th:text="${employee.id}"></td>
<td th:text="${employee.lastName}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.gender}"></td>
<td>
<a @click="deleteEmployee()" th:href="@{'/employee/' + ${employee.id}}">delete</a>
<a th:href="@{'/employee/' + ${employee.id}}">update</a>
</td>
</tr>
</table>
<form method="post">
<input type="hidden" name="_method" value="delete">
</form>
</div>
7.3、添加员工信息
控制器方法:
@RequestMapping(value = "/employee", method = RequestMethod.POST)
public String inserEmployee(Employee employee) {
employeeDao.save(employee);
// 重定向/employee
return "redirect:/employee";
}
HTML文本
<h1>添加员工界面</h1>
<form th:action="@{/employee}" method="post">
<table>
<tr>
<th colspan="2">add employee</th>
</tr>
<tr>
<td>lastName</td>
<td>
<input type="text" name="lastName">
</td>
</tr>
<tr>
<td>Email</td>
<td>
<input type="text" name="email">
</td>
</tr>
<tr>
<td>gender</td>
<td>
<input type="radio" name="gender" value="1">male
<input type="radio" name="gender" value="0">female
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
7.4、修改员工信息
控制器方法:
@RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)
public String toEmployee(@PathVariable("id") Integer id, Model model) {
Employee employee = employeeDao.get(id);
model.addAttribute("employee", employee);
return "employeeUpdate";
}
@RequestMapping(value = "/employee", method = RequestMethod.PUT)
public String updateEmployee(Employee employee) {
employeeDao.save(employee);
return "redirect:/employee";
}
HTML文本
<h1>更新页面</h1>
<form th:action="@{/employee}" method="post">
<input type="hidden" name="_method" value="put">
<input type="hidden" name="id" th:value="${employee.id}">
<table>
<tr>
<th colspan="2">add employee</th>
</tr>
<tr>
<td>lastName</td>
<td>
<input type="text" name="lastName" th:value="${employee.lastName}">
</td>
</tr>
<tr>
<td>Email</td>
<td>
<input type="text" name="email" th:value="${employee.email}">
</td>
</tr>
<tr>
<td>gender</td>
<td>
<input type="radio" name="gender" value="1" th:field="${employee.gender}">male
<input type="radio" name="gender" value="0" th:field="${employee.gender}">female
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="更新">
</td>
</tr>
</table>
</form>
7.5、删除员工信息
控制器方法:
@RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)
public String deleteEmployee(@PathVariable("id") Integer id) {
employeeDao.delete(id);
return "redirect:/employee";
}
HTML文本
有一部分可以看7.2查询所有员工信息的HTML文本
以下是使用了JQuery去调用delete方法
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">
var vue = new Vue({
el:"#app",
methods:{
deleteEmployee() {
// 获取form表单
var form = document.getElementsByTagName("form")[0];
// 将超链接的href属性值赋值给form表单中的action属性
// event.target.href表单当前触发事件的标签
form.action = event.target.href;
form.submit()
// 阻止超链接的默认行文
event.preventDefault();
}
}
})
</script>
—先预定一波,下周一定可以把SpringMVC看完,加油!—
2022/8/15 天气:晴天
8、SpringMVC处理ajax请求
HTML文本:
<body>
<div id="app">
<h1>首页</h1>
<input type="button" value="测试SpringMVC处理ajax" @click="testAjax()"><br>
<input type="button" value="测试@RequestBody注解处理json格式的请求参数" @click="testRequestBody()"><br>
<a th:href="@{/test/ResponseBody}">测试@ReponseBody注解响应浏览器数据</a><br>
<input type="button" value="测试@ResponseBody注解响应json格式的数据" @click="testResponseBody()"><br>
</div>
<script type="text/javascript" th:src="@{/js/vue.js}"></script>
<script type="text/javascript" th:src="@{/js/axios.min.js}"></script>
<script type="text/javascript">
var vue = new Vue({
/**
* axios({
* url:"", //请求路径
* method:"", //请求方式
*
* //以name=value&name=value的方式发送 存放的位置:不管使用的请求方式是get或者是post
* //该请求参数都会被拼接到请求地址后面
* // 此种方式的请求参数可以通过request.getParameter()获取
* param:{}, //请求参数
*
* // 该请求参数会被保存到请求报文的请求体传输到服务器
* // 此种方式的请求参数可以先来获取请求体再通过处理json的jar包进行处理
* // 不能通过request。getParameter()来获取
* data:{} //请求参数 以json格式发送的请求参数 一般为post方法使用
* }).then(response=>{
* console.log(response.data);
* });
*/
el:"#app",
methods:{
testAjax() {
axios.post(
"/SpringMVC/test/ajax?id=1001",
{username:"admin", password:"123456"}
).then(response=>{
console.log(response.data);
});
},
testRequestBody() {
axios.post(
"/SpringMVC/test/RequestBody/json",
{username:"admin", password:"123456", age:23, gender:"男"}
).then(response=>{
console.log(response.data);
});
},
testResponseBody() {
axios.post(
"/SpringMVC/test/ResponseBody/json"
).then(response=>{
console.log(response.data);
});
}
}
});
</script>
</body>
8.1、@RequestBody
1、@RequestBody注解 作用: 将请求体中的内容和控制器方法的形参进行绑定 获取json格式的内容
2、使用@RequestBody注解将json格式的请求参数转换为Java对象
a>导入jackson的依赖
b>在SpringMVC的配置文件中设置mvc:annotation-driven/
c>在处理请求的控制器方法的形参位置,直接设置json格式的请求参数要转换的Java类型的形参使用@RequestBody标识即可
8.2、@RequestBody获取json格式的请求参数
@RequestMapping("/test/ajax")
public void testAjax(Integer id, @RequestBody String requestBody, HttpServletResponse response) throws IOException {
System.out.println("requestBody:" + requestBody);
System.out.println("id:" + id);
response.getWriter().write("hello, axios");
}
@RequestMapping("/test/RequestBody/json")
public void testRequestBody(@RequestBody User user, HttpServletResponse response) throws IOException {
System.out.println(user);
response.getWriter().write("hello, RequestBody");
}
public void testRequestBody(@RequestBody Map<String, Object> map, HttpServletResponse response) throws IOException {
System.out.println(map);
response.getWriter().write("hello, RequestBody");
}
8.3、@ResponseBody
3、@ResponseBody注解 作用: 将所标识的控制器方法的返回值作为响应报文的响应体响应到浏览器
a>导入jackson的依赖
b>在SpringMVC的配置文件中设置<mvc:annotation-driven/>
c>将需要转换为json字符串的Java对象直接作为控制器方法的返回值,再使用@ResponseBody来标识控制器方法则我们就可以将java对象直接转换位json字符串,并响应到浏览器
我们需要再pom.xml中配置jackson依赖
<!-- 处理json格式的包 jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
8.4、@ResponseBody响应浏览器json数据
常用的Java对象转换为JSON的结果:
实体类–>json对象
map–>json对象
list–>json数组
@RequestMapping("/test/ResponseBody")
@ResponseBody
public String testResponseBody() {
return "success";
}
@RequestMapping("/test/ResponseBody/json")
@ResponseBody
public List<User> testResponseBodyJson() {
User user1 = new User(1001, "admin", "123456", 23, "男");
User user2 = new User(1002, "zhangsan", "123", 24, "女");
User user3 = new User(1003, "lisi", "1234", 25, "男");
List<User> users = Arrays.asList(user1, user2, user3);
return users;
}
/*public Map<String, Object> testResponseBodyJson() {
User user1 = new User(1001, "admin", "123456", 23, "男");
User user2 = new User(1002, "zhangsan", "123", 24, "女");
User user3 = new User(1003, "lisi", "1234", 25, "男");
Map<String, Object> map = new HashMap<>();
map.put("1001", user1);
map.put("1002", user2);
map.put("1003", user3);
return map;
}*/
/*public User testResponseBodyJson() {
User user = new User(1001, "admin", "123456", 23, "男");
return user;
}*/
8.5、@RestController注解
复合注解
@RestController注解
不需要为每个方法都添加上@ResponseBody注解了
9、文件的上传和下载
9.1、文件下载
直接上模板
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws
IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers,
statusCode);
//关闭输入流
is.close();
return responseEntity;
}
9.2、文件上传
1、文件上传要求form表单的请求方式必须为post
2、添加属性enctype=“multipart/form-data”
SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息
添加依赖:
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --
>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
在SpringMVC的配置文件中添加配置
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
控制器方法 使用UUID来防止上传的文件重名
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws
IOException {
//获取上传的文件的文件名
String fileName = photo.getOriginalFilename();
//处理文件重名问题
String hzName = fileName.substring(fileName.lastIndexOf("."));
fileName = UUID.randomUUID().toString() + hzName;
//获取服务器中photo目录的路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if(!file.exists()){
file.mkdir();
}
String finalPath = photoPath + File.separator + fileName;
//实现上传功能
photo.transferTo(new File(finalPath));
return "success";
}
2022/8/16 天气:晴天
今天学习了SpringMVC中的两个扩展内容——拦截器和异常处理器,还学习了如何使用注解来配置SpringMVC,用类来代替XM文件。
10、拦截器
主要是实现HandlerInterceptor接口的三个方法,然后在类上加上@Component注解,再在xml文件中进行配置即可
/**
* @author Carl
*
* 配置拦截器的三个方法
* preHandle():在控制器方法执行之前 源码1061行 返回值表示对控制器方法的拦截false或放行 true
* postHandle():在控制器方法执行之后执行
* afterCompletion():在控制器方法执行之后且渲染视图完毕之后执行
*
* 多个拦截器的执行顺序
* 与在springmvc配置文件中的顺序有关 preHandle()会按照配置顺序执行 postHandle()和afterCompletion()会按照反序执行
*
* 若某个preHandle的返回值为false时,在其之前的preHandle方法都会执行
* 之后的post就不会再执行了
* 但是在其之前的拦截器的after方法会执行
*
*
*/
@Component
public class FirstInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("firstInterceptor--->preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("firstInterceptor--->postHandle");
// HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("firstInterceptor--->afterCompletion");
// HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
在配置文件中进行配置主要有三种方法
- 第一种是直接看作bean对象
- 第二种是在类上添加普通组件的注解即@Component对其进行引用
- 第三种是使用<mvc:interceptor>标签进行配置
<!--<mvc:interceptors>
<!– 三种方法 –>
<!– <bean class="com.fzk.interceptor.FirstInterceptor"></bean>–>
<ref bean="firstInterceptor"></ref>
<ref bean="secondInterceptor"></ref>
<ref bean="threeInterceptor"></ref>
<!–<mvc:interceptor>
<!–设置拦截规则 /**/表示任意层目录的请求–>
<mvc:mapping path="/**/"/>
<!– 配置需要排除拦截的请求的请求路径 –>
<mvc:exclude-mapping path="/abc/"/>
<!– 配置拦截器 –>
<ref bean="firstInterceptor"></ref>
</mvc:interceptor>–>
</mvc:interceptors>-->
11、异常处理器
在类上使用@ControllerAdvice注解,将当前类标识为异常处理的组件,在处理异常的方法上使用注解@ExceptionHandler(),值为各种异常的class,这里使用了model来对异常进行处理
/**
* 将当前类标识为异常处理的组件
* @author Carl
*/
@ControllerAdvice
public class TestExceptionController {
@ExceptionHandler(ArithmeticException.class)
public String handleException(Throwable ex, Model model) {
// ex标识再控制器方法所出现的异常
model.addAttribute("ex", ex);
return "Error";
}
}
比如我们在控制器方法中有一个1/0的数学运算错误,即就会跳到上述类中进行处理,然后将其显示在网页Error.html中
<body>
<h1>Error</h1>
<p th:text="${ex}"></p>
</body>
12、注解配置SpringMVC
即我们不需要在xml中进行配置,用类来代替各种配置文件即可。
比如我们在web.xml文件中配置了DispatchServlet和编码Filter,我们就可以在这个类中添加。我们只需要让这个类继承AbstractAnnotationConfigDispatcherServletInitializer,那么我们的SpringMVC就会默认的把他当作web.xml进行处理,用来配置Servlet的上下文
/**
* @author Carl
* 该类用来代替web.xml的
*/
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer{
/**
* 设置一个配置类,来代替Spring的配置文件
* @return
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
/**
* 设置一个配置类,来代替SpringMVC的配置文件
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
/**
* 设置SpringMVC的前端控制器 DispatchServlet的url-pattern
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 设置当前的过滤器
* @return
*/
@Override
protected Filter[] getServletFilters() {
// 创建编码过滤器
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
// 创建请求方式的过滤器
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
}
}
在类中添加注解@Configuration即可标识为配置类,这个用来代替Spring的配置文件
/**
* @author Carl
* 标识为配置类
* 代替Spring的配置文件
*/
@Configuration
public class SpringConfig {
}
SpringMVC的配置文件有点复杂,我们需要先添加@Configuration注解,将其标识为配置类,再实现WebMvcConfigurer接口,然后ctrl+o对需要的方法进行实现。
然后查看以下springmvc.xml中的一些配置如下,进行添加,可以看下注释对@Bean注解的解释
/**
* @author Carl
* 用来代替SpringMVC的配置文件
* 1、扫描组件
* 2、视图解析器
* 3、默认的servlet
* 4、mvc的注解驱动
* 5、视图控制器
* 6、文件上传解析器
* 7、拦截器
* 8、异常解析器
*/
@Configuration
// 1、扫描组件的注解
@ComponentScan("com.atguigu.controller")
// 4、开启MVC的注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
// 3、默认的servlet处理静态资源
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
// 5、视图控制器
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
// 6、文件上传解析器
// 可以将咱们标识的返回值来作为bean进行管理 id:multipartResolver 为方法的方法名
@Bean
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
// 7、拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
FirstInterceptor firstInterceptor = new FirstInterceptor();
registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
}
// 8、异常解析器
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
Properties prop = new Properties();
prop.setProperty("java.lang.ArithmeticException", "error");
simpleMappingExceptionResolver.setExceptionMappings(prop);
simpleMappingExceptionResolver.setExceptionAttribute("ex");
resolvers.add(simpleMappingExceptionResolver);
}
// 2、配置视图解析器
//配置生成模板解析器
@Bean
public ITemplateResolver templateResolver() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
// ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过WebApplicationContext 的方法获得
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(webApplicationContext.getServletContext());
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
//生成模板引擎并为模板引擎注入模板解析器
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//生成视图解析器并未解析器注入模板引擎
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}
2022/8/17 天气:雨天
今天早上7点起来,终于是把SpringMVC给结束了!撒花!今天主要是学习了Mybatis、Spring和SpringMVC三者进行了一个整合的配置,和分页的使用
13、SpringMVC的执行流程
- 用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获。
- DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI),判断请求URI对应的映射:
a) 不存在
i. 再判断是否配置了mvc:default-servlet-handler
ii. 如果没配置,则控制台报映射查找不到,客户端展示404错误
iii. 如果有配置,则访问目标资源(一般为静态资源,如:JS,CSS,HTML),找不到客户端也会展示404
错误
b) 存在则执行下面的流程
3) 根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain执行链对象的形式返回。
4) DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。
5) 如果成功获得HandlerAdapter,此时将开始执行拦截器的preHandler(…)方法【正向】
6) 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
a) HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
b) 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
c) 数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
d) 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
7) Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象。
8) 此时将开始执行拦截器的postHandle(…)方法【逆向】。
9) 根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver进行视图解析,根据Model和View,来渲染视图。
10) 渲染视图完毕执行拦截器的afterCompletion(…)方法【逆向】。
11) 将渲染结果返回给客户端。
一些SpringMVC的常用组件
DispatcherServlet:前端控制器,不需要工程师开发,由框架提供
作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求HandlerMapping:处理器映射器,不需要工程师开发,由框架提供
作用:根据请求的url、method等信息查找Handler,即找到控制器方法
Handler:处理器,需要工程师开发
作用:在DispatcherServlet的控制下Handler对具体的用户请求进行处理HandlerAdapter:处理器适配器,不需要工程师开发,由框架提供
作用:通过HandlerAdapter对处理器(控制器方法)进行执行控制器方法ViewResolver:视图解析器,不需要工程师开发,由框架提供
作用:进行视图解析,得到相应的视图,例如:ThymeleafView、InternalResourceView、RedirectViewView:视图
作用:将模型数据通过页面展示给用户
14、SSM的整合
maven: 3.8.6
mybatis:3.5.10jdk: 11.0.1
spring.version 5.3.1
1、首先先创建一个maven工程
2、添加依赖
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<!--mybatis和spring的整合包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
</dependencies>
<properties>
<spring.version>5.3.1</spring.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
3、配置web.xml文件,springmvc.xml文件,spring.xml文件,mybatis-config.xml文件
web.xml
<!-- 编码过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</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>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置处理请求方式的过滤器 -->
<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>
<!-- 配置前端控制器DispatchServlet -->
<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-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置ContextLoaderListener-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--设置spring配置文件的自定义位置和名称-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
springmvc.xml
<!--扫描控制层组件-->
<context:component-scan base-package="com.abab.ssm.controller"></context:component-scan>
<!--配置视图解析器-->
<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>
<!--配置默认的servlet处理静态资源-->
<mvc:default-servlet-handler />
<!--开启mvc的注解驱动-->
<mvc:annotation-driven />
<!--配置视图控制器-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
spring.xml
<!-- 扫描组件(除控制层) -->
<context:component-scan base-package="com.fzk.ssm">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 引入管理连接sql的properties文件 -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
开启事务的注解驱动
将使用注解@Transactional标识的方法或类中所有的方法进行事务管理
-->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 配置SQLSessionFactoryBean 可以直接在spring的ioc中获取SqlSessionFactory对象 -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 设置mybatis的核心配置文件的路径 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.fzk.ssm.pojo"></property>
</bean>
<!-- 配置mapper接口,通过SqlSession创建代理实现类对象并交给IOC处理 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.fzk.ssm.mapper"></property>
</bean>
mybatis-config.xml
PS:这里因为有些东西在spring.xml文件中配置过了,所以在mybatis核心配置文件中没有写很多东西
<configuration>
<!--
MyBatis核心配置文件中必须按照指定的顺序来配置
"(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,
reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".
-->
<settings>
<!--将下划线映射为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
</configuration>
其他的一些配置
jdbc.peoperties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}%m (%F:%L) n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
其余的像一些mybatis中的mapper.xml文件,就是像之前mybatis教程中的一样即可
4、测试分页功能
因为在spring.xml和springmvc.xml文件中配置了注解,所以我们可以直接通过注解来声明一个bean对象进行处理
例如在EmployeeServiceImpl.java文件中添加的注解
@Transactional是声明为事务管理
@Autowired自动注入
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
@Autowired
private EmployeeMapper employeeMapper;
@Override
public List<Employee> getAllEmployee() {
return employeeMapper.getAllEmployee();
}
@Override
public PageInfo<Employee> getEmployeePage(Integer pageNum) {
PageHelper.startPage(pageNum, 4);
List<Employee> list = employeeMapper.getAllEmployee();
PageInfo<Employee> page= new PageInfo<>(list, 5);
return page;
}
}
在Controller层中添加方法
@Controller
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@RequestMapping(value = "/employee/page/{pageNum}", method = RequestMethod.GET)
public String getEmployeePage(@PathVariable("pageNum") Integer pageNum, Model model) {
// 获取员工的分页信息
PageInfo<Employee> page = employeeService.getEmployeePage(pageNum);
// 将分页数据共享在请求域中
model.addAttribute("page", page);
return "employeeList";
}
@GetMapping("/employee")
public String getAllEmployee(Model model) {
List<Employee> list = employeeService.getAllEmployee();
model.addAttribute("list", list);
// 跳转到employee_list.html
return "employeeList";
}
}
在index.html文件中添加超链接
<body>
<h1>首页</h1>
<a th:href="@{/employee/page/1}">查询员工的分页信息</a>
</body>
测试分页功能 EmployeeList.html
<body>
<table>
<tr>
<th colspan="6">员工列表</th>
</tr>
<tr>
<th>序号</th>
<th>员工姓名</th>
<th>年龄</th>
<th>性别</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<tr th:each="employee, status : ${page.list}">
<td th:text="${status.count}"></td>
<td th:text="${employee.empName}"></td>
<td th:text="${employee.age}"></td>
<td th:text="${employee.gender}"></td>
<td th:text="${employee.email}"></td>
<td>
<a href="">修改</a>
<a href="">删除</a>
</td>
</tr>
</table>
<div style="text-align: center;">
<a th:if="${page.hasPreviousPage}" th:href="@{/employee/page/1}">首页</a>
<a th:if="${page.hasPreviousPage}" th:href="@{'/employee/page/'+${page.prePage}}">上一页</a>
<span th:each="num : ${page.navigatepageNums}">
<a th:if="${page.pageNum == num}" style="color: red;" th:href="@{'/employee/page/'+${num}}" th:text="'['+${num}+']'"></a>
<a th:if="${page.pageNum != num}" th:href="@{'/employee/page/'+${num}}" th:text="${num}"></a>
</span>
<a th:if="${page.hasNextPage}" th:href="@{'/employee/page/'+${page.nextPage}}">下一页</a>
<a th:if="${page.hasNextPage}" th:href="@{'/employee/page/'+${page.pages}}">末页</a>
</div>
</body>
❀SSM完结撒花❀
期间在启动Tomcat服务器的时候出现了错误,百度之后我们可以通过Rebuild模块解决
Module ‘spring_mvc_ajax’ production: java.lang.ClassCastException:
如果你想在idea中查看源码的话,不是.class文件
可以使用CMD进入到pom.xml工程文件下 执行这句话即可下载源码文件
mvn dependency:resolve -Dclassifier=sources
最后
以上就是暴躁康乃馨为你收集整理的SSM学习日记--尚硅谷视频(3)2022/8/9 天气:晴天2022/8/10 天气:晴天2022/8/13 天气:晴天2022/8/14 天气:晴天2022/8/15 天气:晴天2022/8/16 天气:晴天2022/8/17 天气:雨天的全部内容,希望文章能够帮你解决SSM学习日记--尚硅谷视频(3)2022/8/9 天气:晴天2022/8/10 天气:晴天2022/8/13 天气:晴天2022/8/14 天气:晴天2022/8/15 天气:晴天2022/8/16 天气:晴天2022/8/17 天气:雨天所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复