我的SSM框架自学3
SpringMVC
一,SpringMVC介绍
mvc是一种三层架构(表述层、业务逻辑层、数据访问层)的思想,将软件按照模型、视图、控制器划分;
M:model,模型层,指工程中的JavaBean,处理数据
JavaBean有两类:
a>实体类Bean:专门存储业务数据,如Student,User等;
b>业务处理类Bean:指Service或Dao对象,专门用于处理业务逻辑和数据访问;
V:View,视图层,工程中的html或jsp页面,与用户交互,展示数据;
C:Controller,控制层,工程中的Servlet,接收请求和响应浏览器;
MVC工作流程
用户通过视图层发送请求到服务器,在服务器中被Controller层接收,Controller调用对应的模型Model层处理请求,处理完毕把结果返回到Controller,Controller在根据请求处理的结果找到相应的View视图,渲染数据后响应给浏览器;
什么是SpringMVC
SpringMVC是SPring为表述层开发提供的一整套解决方案,表述层表示前台页面和后台Servlet,SpringMVC封装了Servlet,所有的请求都是通过DispatcherServlet前端控制器来处理的;
二、配置文件
pom.xml需配置的依赖
<!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.6.RELEASE</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>Web.xml需配置的文件
<?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"><!-- 配置SpringMVC的前端控制器DispatcherServlet --><servlet><servlet-name>springMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--修改前端控制器DispatcherServlet默认的文件名称和文件的存放位置classpath:放在类路径java或resource目录下springmvc.xml:修改默认的文件名--><init-param><param-name>contextConfigLocation</param-name><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请求路径的请求/ 所匹配的请求都要交给前端控制器DispatcherServlet所处理/* 表示能匹配所有的请求*.do表示匹配请求路径为.do的才能处理--><url-pattern>/</url-pattern></servlet-mapping>
</web-app>springmvc.xml配置文件
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--扫描注解 : 只扫描controller层 --><context:component-scan base-package="com.demo.controller"></context:component-scan><!-- DispatcherServlet内部加载,配置Thymeleaf视图解析器,解析视图 --><bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="UTF-8"/><!-- templateEngine:模版引擎 templateResolver:模版解析 --><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!-- 物理视图:访问的路径:/WEB-INF/templates/index.html --><!-- 逻辑视图(把前缀和后缀去掉):简化成:index --><!-- 视图前缀 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 视图后缀 --><property name="suffix" value=".html"/><!-- templateMode模版模型,以HTML5为模版模型 --><property name="templateMode" value="HTML5"/><!-- 视图默认编码:UTF-8 --><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean></beans>三、@RequestMapping注解
1.标记的位置
(1)加在类上
设置映射请求的请求路径的初始信息,相当于多了一层目录
(2)加在方法上
设置映射请求的请求路径的具体信息
2.属性
2.1Value属性
通过请求的请求路径匹配请求,value属性是数组类型,即发送请求的请求路径匹配value属性中的任何一个值,被注解所标识的方法处理(一个方法可以处理多个请求)
@RequestMapping({"/user","/abc"})
public String t1(){return "index";
}2.2Method属性
通过指定请求方式来匹配请求,是RequestMethod类型的数组,支持多个请求方式匹配请求
method = RequestMethod.GET
method = RequestMethod.POST
2.3Param属性
浏览器发送请求的请求参数必须满足param属性的设置
四种表达式:
"param"
"!param"
"param!=value"
"param=value"
3.@RequestMapping派生注解
a>@GetMapping(value="")只处理Get请求
b>@PostMapping(value="")只处理Post请求
c>@PutMapping(value="")只处理Put请求
d>@DeleteMapping(value="")只处理Delete请求
四、获取请求参数
1.通过ServletAP获取
在控制器方法的形参位置设置HttpServletRequest类型的形参,不推荐使用这种方式,因为已经封装了servlet;
<form th:action="@{/param/servletAPI}" method="post">用户名:<label><input type="text" name="username"/></label>密 码:<label><input type="password" name="password"/></label>简 介:<label><input type="text" name="describe"/></label><input type="submit" value="登录">
</form>
@RequestMapping("/param/servletAPI")
public String login(HttpServletRequest request){String username = request.getParameter("username");String password = request.getParameter("password");System.out.println("用户名:"+username+",密码:"+password);return "success";
}2. 通过控制器方法的形参获取
需要注意形参的名字和请求参数的名字一致;
@RequestMapping("/param")
public String login2(String username,String password){System.out.println("username:"+username+",password:"+password);return "success";
}3.使用@RequestParam注解获取参数
如果形参和请求参数不一样,那么就可以使用@RequestParam指定请求参数名和形参绑定
@RequestParam的属性:
require是否必须传的参数(默认必须)
defaultValue:参数的默认值
<form th:action="@{/param}" method="post">用户名:<label><input type="text" name="userName"/></label>密 码:<label><input type="password" name="password"/></label>简 介:<label><input type="text" name="describe"/></label><input type="submit" value="登录">
</form>
@RequestMapping("/param")
public String login2(@RequestParam("userName")String username,String password){System.out.println("username:"+username+",password:"+password);return "success";
}4.获取pojo实体类类型参数
保证实体类的属性和请求参数的名称一样,那就可以把请求参数的值封装到实体类类型的形参中
<form th:action="@{/param/pojo}" method="post">用户名:<label><input type="text" name="username"/></label>密 码:<label><input type="password" name="password"/></label>简 介:<label><input type="text" name="describe"/></label><input type="submit" value="登录">
</form>
@RequestMapping("/param/pojo")
public String login3(User user){System.out.println(user);return "success";
}5.使用@RequestHeader注解获取请求头信息
将请求头信息和控制器方法的形参绑定
6.使用@CookieValue注解获取Cookie信息
将Cookie信息和控制器方法的形参绑定 ,例:获取cookie属性名为username的值

7.使用@RequestParam注解获取请求参数信息
将请求参数信息和控制器方法的形参绑定
五、解决请求参数乱码
form表单get请求乱码问题,tomcat添加以下配置

form表单post请求乱码问题,web.xml配置过滤器,SpringMVC处理编码的过滤器一定要配置在其他过滤器之前,否则无效;
<!-- 设置Spring的编码过滤器 --><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!-- 设置自定义编码为UTF-8 --><!-- 设置请求的编码 --><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>六、域对象共享数据
1.request域共享数据
a>使用ModelAndView共享数据(底层原理为这一种)
ModelAndView包含Model和View的功能;Model向请求域中共享数据,View设置逻辑视图实现页面跳转,控制器方法一定要将ModelAndView作为对象返回;
@RequestMapping("/model/test")
public ModelAndView test(ModelAndView mav){mav.addObject("msg","hello,modelAndView");mav.setViewName("success");return mav;
}b>使用Model共享数据(推荐使用这一种)
@RequestMapping("/model/test1")public String test1(Model model){model.addAttribute("msg1","hello,model");return "success";}c>使用ModelMap共享数据
@RequestMapping("/model/test2")public String test2(ModelMap modelMap){modelMap.addAttribute("msg2","hello,modelMap");return "success";}d>使用map共享数据
@RequestMapping("/model/test3")public String test3(Map<String,Object> map){map.put("msg3","hello,map");return "success";}2.会话域共享数据(浏览器关闭就没有数据)
会话:浏览器给服务器发起连接请求,连接上服务器就是一次会话,一次会话可以有多个请求,如果浏览器关闭,会话的数据就会消失;如果不做任何操作,session会话的存储时间默认30分钟,会话会有个钝化、活化的过程
使用ServletAPI来共享数据
@RequestMapping("/demo/test4")
public String test4(HttpSession session){
// HttpSession session1 = req.getSession();session.setAttribute("username","hangman");return "success";
}3.应用域共享数据(服务器tomcat关闭就没有这个数据了)
使用ServletAPI来共享数据
@RequestMapping("/demo/test5")public String test5(HttpSession session){ServletContext application = session.getServletContext();application.setAttribute("password","123456");return "success";}七、SpringMVC的视图
失败转发,成功重定向
1.返回值没有任何的前缀就是thymeleaf视图
@RequestMapping("/param/pojo")
public String login4(){return "success";
}2.返回值有前缀forward:就是转发视图,只是服务器转发,没有经过thymeleaf解析器,地址栏不变;
@RequestMapping("/param/pojo")
public String login4(){return "forward:/test/model";
}3.返回值有前缀redirect:就是重定向视图,地址栏发生变化;
@RequestMapping("/param/pojo")
public String login4(){return "redirect:/demo/test5";
}4.视图控制器
为当前的请求直接设置视图名称实现页面跳转
springmvc-config.xml配置文件(添加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/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 开启mvc的注解驱动--><mvc:annotation-driven/><!--视图控制器:为当前的请求直接设置视图名称实现页面跳转如果不配置mvc的注解驱动,那么index页面的其他请求访问不到会报404,只有配置在视图控制器的请求路径才能处理;使用mvc注解驱动,可以处理视图控制器和@RequestMapping的控制器方法;--><mvc:view-controller path="/" view-name="index"/></beans>八、RESTful
表现层资源状态转移(很抽象的概念),是一种风格,把你要访问的资源(浏览器的图片,数据库的一张表等等)以及对资源的操作体现在请求路径上
1.REST风格
提倡URL地址使用统一的风格设计,各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为URL地址的一部分,保证整体风格的一致性;
例:
查询所有用户信息 /user -->get
根据id查询用户信息 /user/1 -->get
添加用户信息 /user -->post
修改用户信息 /user -->put
根据id删除用户信息 /user/1 -->delete
form表单目前只提供get和post请求,若要发送put和delete请求,需要在web.xml文件中配置一个过滤器HiddenHttpMethodFilter,配置过滤器之后,
发送请求必须满足两个条件,才能把请求方式转换为put或delete
1.当前请求必须为post
2.form表单里携带请求参数_method,且值设置为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>
<form th:action="@{/user}" method="post"><input type="hidden" name="_method" value="put"><input type="submit" value="修改用户">
</form>
<form th:action="@{/user/1}" method="post"><input type="hidden" name="_method" value="delete"><input type="submit" value="删除用户">
</form>2.注解@RequestBody获取请求体参数
将请求体的内容和控制器方法的形参进行绑定,使用@RequestBody注解将json格式的请求参数转换为java对象;
在处理请求的控制器方法的形参位置,使用@RequestBody注解设置json格式的请求参数要转换的java类型的形参

控制器方法的形参使用实体类类型的参数接收post请求传递过来的参数
@Controller
@RequestMapping("/user")
public class UserController{@PostMapping("/login")@RequestBodypublic User selectUser(HttpServletResponse response,User user) throws IOException {return user;}}
<!-- 导入jackson依赖坐标 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.1</version></dependency>3.注解@ResponseBody 响应数据
将java对象转换为json字符串作为控制器方法的返回值,响应一个user对象
@RequestMapping("/login")@ResponseBodypublic User login(){return new User();}4.使用@PathVariable获取请求参数作为地址的信息

