SpringMVC 是 Spring 为表述层开拓供应的一整套完备的办理方案。在表述层框架历经 Strust、WebWork、Strust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开拓的首选方案。
注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台servlet
1.3 SpringMVC的特点Spring 家族原生产品,与 IOC 容器等根本举动步伐无缝对接基于原生的Servlet,通过功能强大的前端掌握器DispatcherServlet,对要乞降相应进行统一处理表述层各细分领域须要办理的问题全方位覆盖,供应全面办理方案代码清新简洁,大幅度提升开拓效率内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可性能卓著,尤其适宜当代大型、超大型互联网项目哀求2 HelloWorld2.1 Maven打包办法: <packaging>war</packaging>
添加依赖:
<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>
scope(依赖范围):provided(已被供应),表示做事器已经供应该依赖,以是此依赖不会被打包
2.2 配置web.xml注册SpringMVC的前端掌握器DispatcherServlet
默认配置办法此配置浸染下,SpringMVC的配置文件默认位于WEB-INF下,默认名称为<servlet-name>,例如,以下配置所对应SpringMVC的配置文件位于WEB-INF下,文件名为springMVC-servlet.xml
<!-- 配置SpringMVC的前端掌握器,对浏览器发送的要求统一进行处理 --><servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class></servlet><servlet-mapping> <servlet-name>springMVC</servlet-name> <!-- 设置springMVC的核心掌握器所能处理的要求的要求路径 /所匹配的要求可以是/login或.html或.js或.css办法的要求路径 但是/不能匹配.jsp要求路径的要求 --> <url-pattern>/</url-pattern></servlet-mapping>
扩展配置办法(推举)
可通过init-param标签设置SpringMVC配置文件的位置和名称,通过load-on-startup标签设置SpringMVC前端掌握器DispatcherServlet的初始化韶光
<?xml version=34;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的前端掌握器,对浏览器发送的要求统一进行处理 --> <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></web-app>
注:<url-pattern>标签中利用/和/的差异:
/所匹配的要求可以是.html或.js或.css办法的要求路径,但是/不能匹配.jsp要求路径的要求,
避免在访问jsp页面时,要求被DispatcherServlet处理而找不到相应的页面。
/则能够匹配所有要求,例如在利用过滤器时,若须要对所有要求进行过滤,就须要利用/的写法
2.3 创建springMVC的配置文件spring配置文件
<?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 https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置包扫描--> <context:component-scan base-package="com.birdy"></context:component-scan> <!-- 配置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>
2.4 页面
前端页面文件放置在路径src/main/webapp/WEB-INF/templates/下
<!--index.html--><!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>首页</title></head><body><h1>hello world!</h1></body></html>
2.5 创建要求掌握器
由于前端掌握器对浏览器发送的要求进行了统一的处理,但是不同的要求可能须要不同的处理过程,因此须要创建单独处理要求的类,即要求掌握器
要求掌握器中处理要求的方法成为掌握器方法
由于SpringMVC的掌握器由一个POJO(普通的Java类)担当,因此须要通过@Controller表明将其标识为一个掌握层组件,交给Spring的IoC容器管理,此时SpringMVC才能够识别掌握器的存在
@Controllerpublic class HelloController { @RequestMapping("/") public String index(){ //掌握前将前端传过来的路径映射到指定文件 return "index"; //将要求转发到index.html文件 }}
注:之以是 return "index";就可以映射到index.html文件,是由于在springMVC.xml配置了视图解析器处理要求的规则,即自动添加了前缀文件路径和后缀文件类型
2.6 总结浏览器发送要求,若要求地址符合前端掌握器的url-pattern,该要求就会被前端掌握器DispatcherServlet处理。前端掌握器会读取SpringMVC的核心配置文件,通过扫描组件找到掌握器,将要求地址和掌握器中@RequestMapping表明的value属性值进行匹配,若匹配成功,该表明所标识的掌握器方法便是处理要求的方法。处理要求的方法须要返回一个字符串类型的视图名称,该视图名称会被视图解析器解析,加上前缀和后缀组成视图的路径,通过Thymeleaf对视图进行渲染,终极转发到视图所对应页面
3 @RequestMapping表明浸染:顾名思义,@RequestMapping`表明的浸染便是将要乞降处理要求的掌握器方法关联起来,建立映射关系。SpringMVC 吸收到指定的要求,就会来找到在映射关系中对应的掌握器方法来处理这个要求。
3.1 位置@RequestMapping标识一个类:设置要求路径的初始信息,作为类里所有掌握器方法映射路径的的公共前缀部分@RequestMapping标识一个方法:设置映射要求要求路径的详细信息@Controller@RequestMapping("/test")public class RequestMappingController {//此时映射的要求路径为:/test/testRequestMapping @RequestMapping("/testRequestMapping") public String testRequestMapping(){ return "success"; }}
3.2 属性value
value属性通过要求的要求地址匹配要求映射,@RequestMapping表明的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";}
method@RequestMapping表明的method属性通过定义要求办法(get或post)匹配要求映射method属性是一个RequestMethod类型的数组,表示该要求映射能够匹配多种要求办法的要求
若一个要求的要求地址知足value属性,但是要求办法不知足method属性,则浏览器报错405:Request method 'xxx' 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";}
注:
对付处理指定要求办法的掌握器方法,SpringMVC中供应了@RequestMapping的派生表明
处理get要求的映射-->@GetMapping处理post要求的映射-->@PostMapping处理put要求的映射-->@PutMapping处理delete要求的映射-->@DeleteMapping常用的要求办法有get,post,put,delete,但是目前浏览器只支持get和post,若在form表单提交时,为method设置了其他要求办法的字符串(put或delete),则按照默认的要求办法get处理。
若要发送put和delete要求,则须要通过spring供应的过滤器HiddenHttpMethodFilter,在RESTful部分会讲到
params(理解)@RequestMapping表明的params属性通过要求的要求参数匹配要求映射,@RequestMapping表明的params属性是一个字符串类型的数组,可以通过四种表达式设置要求参数和要求映射的匹配关系
"param":哀求要求映射所匹配的要求必须携带param要求参数"!param":哀求要求映射所匹配的要求必须不能携带param要求参数"param=value":哀求要求映射所匹配的要求必须携带param要求参数且param=value"param!=value":哀求要求映射所匹配的要求必须携带param要求参数但是param!=value
示例:
<a th:href="@{/test(username='admin',password=123456)">测试@RequestMapping的params属性-->/test</a><br>
@RequestMapping( value = {"/testRequestMapping", "/test"} ,method = {RequestMethod.GET, RequestMethod.POST} ,params = {"username","password!=123456"}//表示要求必须携带username属性,值任意;必须携带password属性,且值必须为123456)public String testRequestMapping(){ return "success";}
注:
thymeleaf利用@{}填写路径,且自带tomcat中设置的默认文本路径利用()填写要求参数
headers(理解)@RequestMapping表明的headers属性通过要求的要求头信息匹配要求映射。@RequestMapping表明的headers属性是一个字符串类型的数组,可以通过四种表达式设置要求头信息和要求映射的匹配关系
"header":哀求要求映射所匹配的要求必须携带header要求头信息"!header":哀求要求映射所匹配的要求必须不能携带header要求头信息"header=value":哀求要求映射所匹配的要求必须携带header要求头信息且header=value"header!=value":哀求要求映射所匹配的要求必须携带header要求头信息且header!=value
若当前要求知足@RequestMapping表明的value和method属性,但是不知足headers属性,此时页面显示404缺点,即资源未找到
3.3 SpringMVC支持ant风格的路径?:表示任意的单个字符
:表示任意的0个或多个字符
:表示任意的一层或多层目录
把稳:在利用时,只能利用//xxx的办法
3.4 路径中的占位符(重点)原始办法:/deleteUser?id=1rest办法:/deleteUser/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
4 SpringMVC获取要求参数4.1 通过ServletAPI获取
将HttpServletRequest作为掌握器方法的形参,此时HttpServletRequest类型的参数便是封装了当前要求报文的工具
<a th:href="@{/servlet(username='admin',password=123)}">测试servlet传参</a>
@RequestMapping("/servlet")public String testParam(HttpServletRequest request){String username = request.getParameter("username");String password = request.getParameter("password");System.out.println("username:"+username+",password:"+password);return "target";}//打印结果:username:admin,password:123
4.2 通过SpringMVC掌握器方法的形参获取要求参数
在特定情形下才会利用原始Servlet传参,SpringMVC自带形参匹配功能方便传参,在掌握器方法的形参位置,设置和要求参数同名的形参,当浏览器发送要求,匹配到要求映射时,在DispatcherServlet中就会将要求参数赋值给相应的形参,推举利用。
<a th:href="@{/default(username='birdy',password=123)}">测试SringMVC形参办法</a>
@RequestMapping("/default")public String testDefault(String username, Integer password){System.out.println("username:"+username+",password:"+password);return "target";}//打印结果:username:birdy,password:123
4.3 @RequestParam
@RequestParam: 将要求参数和掌握器方法的形参创建映射关系
@RequestParam表明一共有三个属性:
value:指定为形参赋值的要求参数的参数名required:设置是否必须传输此要求参数,默认值为true值为true时,则当前要求必须传输value所指定的参数名,若没有传输该要求参数,且没有设置defaultValue属性,则页面报错400:Required String parameter 'xxx' is not present; 值为false,则当前要求不是必须传输value所指定的要求参数。若没有传,则表明所标识的形参的值为nulldefaultValue:不管required属性值为true或false,当value所指定的要求参数没有传输或传输的值为空""时,则利用默认值为形参赋值@RequestMapping("/default")public String testDefault( @RequestParam(value = "username", required = false) String username,@RequestParam(value = "password", required = false) String password ) {System.out.println("username:"+username+",password:"+password);return "target";}//打印结果:username:birdy,password:123
4.4 @RequestHeader
@RequestHeader是将要求头信息和掌握器方法的形参创建映射关系
@RequestHeader表明一共有三个属性:value、required、defaultValue,用法同@RequestParam
@RequestMapping("/header")public String testHeader(@RequestHeader(value = "Host") String host, @RequestHeader(value = "Accept-Encoding") String code){ System.out.println(host+""+code); return "target";}
4.5 @CookieValue
@CookieValue是将cookie数据和掌握器方法的形参创建映射关系
@CookieValue表明一共有三个属性:value、required、defaultValue,用法同@RequestParam
session依赖于cookie,cookie在第一次要求时由做事器创建,通过相应头返回给浏览器并保存在浏览器中,cookie默认在浏览器关闭后自动打消
4.6 办理获取要求参数的乱码问题办理获取要求参数的乱码问题,可以利用SpringMVC供应的编码过滤器CharacterEncodingFilter,须要在web.xml中进行注册
<!--配置springMVC的编码过滤器--><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>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param></filter><filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/</url-pattern></filter-mapping>
注:SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前,否则无效
5 域工具共享数据5.1 servlet四种域工具当前页面 (pagecontext)
生命周期:当对JSP的要求时开始,当相应结束时销毁。浸染范围:全体JSP页面,是四大浸染域中最小的一个,即超过这个页面就不能够利用了。(以是利用pageContext工具向其它页面通报参数是不可能的.)常用功能:获取其它八大隐式工具,可以认为是一个入口工具。获取其所有域中的数据跳转到其他资源,其身上供应了forward和include方法,简化重定向和转发的操作。一次要求(requset)
设定的工具在一次要求中有效,一次要求大略的理解为用户点击一次超链接,当用户第二次点击的时候浏览器又发送一个新的要求给做事器,以是在一次点击后,后台不管跳转多少个servlet,jsp都算是一次要求,而后台在所跳转的任何界面都能访问设定的工具(如登录界面向其他管理界面传送登录的用户信息等)
生命周期:在service 方法调用前由做事器创建,传入service方法。全体要求结束,request生命结束。浸染范围:全体要求链(要求转发也存在)。常用功能: 在全体要求链中共享数据。例如在Servlet 中处理好的数据交给Jsp显示,此时参数就可以放置在Request域中带过去
一次会话(session)
生命周期:在第一次调用 request.getSession() 方法时,做事器会检讨是否已经有对应的session,如果没有就在内存 中创建一个session并返回。当一段韶光内session没有被利用(默认为30分钟),则做事器会销毁该session。如果做事器非正常关闭(强行关闭),没有到期的session也会随着销毁。如果调用session供应的invalidate(),可以立即销毁session。把稳:做事器正常关闭,再启动,Session工具会进行钝化和活化操作。同时如果做事器钝化的韶光在session 默认销毁韶光之内,则活化后session还是存在的。否则Session不存在。如果JavaBean 数据在session钝化时,没有实现Serializable 则当Session活化时,会消逝。浸染范围:一次会话,直到浏览器关闭或默认30分钟没有操作session销毁。常用功能:保存用户登录信息。ServletContext(全体项目)
生命周期:当做事器启动时该域工具,当做事器关闭或Web运用被移除时,ServletContext工具随着销毁。浸染范围:全体Web运用。相称于web运用的全局变量(如统计网站的访问率等)常用功能:在不同Servlet 之间转发,读取资源文件。5.2 request域工具共享数据利用原生ServletAPI@RequestMapping("/testServletAPI")public String testServletAPI(HttpServletRequest request){ request.setAttribute("ServletRequestScope", "hello,servletAPI"); return "success";}
<!--thymleaf: 从request域中获取共享数据 --><p th:text="${ServletRequestScope}"></p>
ModelAndView
@RequestMapping("/testModelAndView")public ModelAndView testModelAndView(){ / ModelAndView有Model和View的功能 Model紧张用于向要求域共享数据 View紧张用于设置视图,实现页面跳转 / ModelAndView mav = new ModelAndView(); //向要求域共享数据 mav.addObject("ModelAndViewRequestScope", "hello,ModelAndView"); //设置视图,实现页面跳转 mav.setViewName("success"); return mav;}
Model
@RequestMapping("/testModel")public String testModel(Model model){ model.addAttribute("ModelRequestScope", "hello,Model"); return "success";}
Map
@RequestMapping("/testMap")public String testMap(Map<String, Object> map){ map.put("testScope", "hello,Map"); return "success";}
ModelMap
@RequestMapping("/testModelMap")public String testModelMap(ModelMap modelMap){ modelMap.addAttribute("testScope", "hello,ModelMap"); return "success";}
Model、ModelMap、Map的关系
Model、ModelMap、Map类型的参数实在实质上都是 BindingAwareModelMap类型的
public interface Model{}public class ModelMap extends LinkedHashMap<String, Object> {}public class ExtendedModelMap extends ModelMap implements Model {}public class BindingAwareModelMap extends ExtendedModelMap {}
5.3 session
@RequestMapping("/testSession")public String testSession(HttpSession session){ session.setAttribute("testSessionScope", "hello,session"); return "success";}
<!--thymleaf: 从session域中获取共享数据 --><p th:text="${sesson.testSessionScope}"></p>
5.4 ServletContext(Application)域
@RequestMapping("/testApplication")public String testApplication(HttpSession session){ServletContext application = session.getServletContext(); application.setAttribute("testApplicationScope", "hello,application"); return "success";}
<!--thymleaf: 从servlet域中获取共享数据 --><p th:text="${application.testApplicationScope}"></p>
6 SpringMVC的视图
SpringMVC中的视图是View接口,视图的浸染渲染数据,将模型Model中的数据展示给用户
SpringMVC视图的种类很多,默认有转发视图和重定向视图
当工程引入jstl的依赖,转发视图会自动转换为JstlView
若利用的视图技能为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后所得到的是ThymeleafView
6.1 ThymeleafView当掌握器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的终极路径,会通过转发的办法实现跳转
@RequestMapping("/testHello")public String testHello(){ return "hello";}
6.2 转发视图
SpringMVC中默认的转发视图是InternalResourceView
SpringMVC中创建转发视图的情形:
当掌握器方法中所设置的视图名称以forward:为前缀时,创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀forward:去掉,剩余部分作为终极路径通过转发的办法实现跳转。
例如:
forward:/forward:/employee
@RequestMapping("/testForward")public String testForward(){ return "forward:/testHello";}
视图掌握器view-controller
6.3 重定向视图SpringMVC中默认的重定向视图是RedirectView
当掌握器方法中所设置的视图名称以redirect:为前缀时,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀redirect:去掉,剩余部分作为终极路径通过重定向的办法实现跳转
@RequestMapping("/testRedirect")public String testRedirect(){ return "redirect:/testHello";}
6.4 视图掌握器view-controller
当掌握器方法中,仅仅用来实现页面跳转,即只须要设置视图名称时,可以将处理器方法利用view-controller标签进行表示,在spring配置文件中添加
<!--path:设置处理的要求地址view-name:设置要求地址所对应的视图名称--><mvc:view-controller path="/" view-name="index"></mvc:view-controller><!--开启mvc表明驱动--><mvc:annotation-driven />
此时就可以删除掌握器方法
@RequestMapping("/") public String index(HttpServletRequest request){ return "index"; }
注:
当SpringMVC中设置任何一个view-controller时,其他掌握器中的要求映射将全部失落效,此时须要在SpringMVC的核心配置文件中设置开启mvc表明驱动的标签:<mvc:annotation-driven />
7 Restful7.1 RESTful简介REST:Representational State Transfer,表现层资源状态转移。
a>资源
资源是一种看待做事器的办法,即,将做事器看作是由很多离散的资源组成。每个资源是做事器上一个可命名的抽象观点。由于资源是一个抽象的观点,以是它不仅仅能代表做事器文件系统中的一个文件、数据库中的一张表等等详细的东西,可以将资源设计的要多抽象有多抽象,只要想象力许可而且客户端运用开拓者能够理解。与面向工具设计类似,资源因此名词为核心来组织的,首先关注的是名词。一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端运用,可以通过资源的URI与其进行交互。
b>资源的表述
资源的表述是一段对付资源在某个特定时刻的状态的描述。可以在客户端-做事器端之间转移(交流)。资源的表述可以有多种格式,例如HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格式可以通过协商机制来确定。要求-相应方向的表述常日利用不同的格式。
c>状态转移
状态转移说的是:在客户端和做事器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。
7.2 实现详细说,便是 HTTP 协议里面,四个表示操作办法的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
REST 风格提倡 URL 地址利用统一的风格设计,从前到后各个单词利用斜杠分开,不该用问号键值对办法携带要求参数,而是将要发送给做事器的数据作为 URL 地址的一部分,以担保整体风格的同等性。
操作
传统办法
REST风格
查询操作
getUserById?id=1
user/1-->get要求办法
保存操作
saveUser
user-->post要求办法
删除操作
deleteUser?id=1
user/1-->delete要求办法
更新操作
updateUser
user-->put要求办法
7.3 过滤器HiddenHttpMethodFilter由于浏览器只支持发送get和post办法的要求,那么该如何发送put和delete要求呢?
SpringMVC 供应了 HiddenHttpMethodFilter 帮助我们将 POST 要求转换为 DELETE 或 PUT 要求
HiddenHttpMethodFilter处理put和delete要求的须要知足条件:
当前要求的要求办法必须为post当前要求必须传输要求参数_method知足以上条件,HiddenHttpMethodFilter过滤器就会将当前要求的要求办法转换为要求参数_method的值,因此要求参数_method的值才是终极的要求办法
在web.xml中注册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>
注:目前为止,SpringMVC中供应了两个过滤器:CharacterEncodingFilter和HiddenHttpMethodFilter
在web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter
缘故原由:CharacterEncodingFilter 中通过 request.setCharacterEncoding(encoding) 方法设置字符集的,哀求前面不能有任何获取要求参数的操作。而 HiddenHttpMethodFilter 正好有一个后去要求参数_method当作真实要求办法的操作
8 RESTful案例准备事情和传统 CRUD 一样,实现对员工信息的增编削查。
搭建环境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"> <!--配置编码过滤器--> <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>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/</url-pattern> </filter-mapping> <!--配置处理要求办法put和delete的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> <!--配置SpringMVC的前端掌握器DispatcherServlet--> <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></web-app>
spring配置文件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" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--扫描组件--> <context:component-scan base-package="com.birdy.rest"></context:component-scan> <!--配置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> <!--配置视图掌握器--> <mvc:view-controller path="/" view-name="index"></mvc:view-controller> <mvc:view-controller path="/toAdd" view-name="employee_add"></mvc:view-controller> <!--开放对静态资源的访问--> <mvc:default-servlet-handler /> <!--开启mvc表明驱动--> <mvc:annotation-driven /></beans>
实体类
package com.birdy.mvc.bean;public class Employee { private Integer id; private String lastName; private String email; //1 male, 0 female private Integer gender; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getGender() { return gender; } public void setGender(Integer gender) { this.gender = gender; } public Employee(Integer id, String lastName, String email, Integer gender) { super(); this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; } public Employee() { }}
准备dao仿照数据
package com.birdy.mvc.dao;import java.util.Collection;import java.util.HashMap;import java.util.Map;import com.birdy.mvc.bean.Employee;import org.springframework.stereotype.Repository;@Repositorypublic 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); }}
功能清单
功能
URL 地址
要求办法
访问首页√
/
GET
查询全部数据√
/employee
GET
删除√
/employee/2
DELETE
跳转到添加数据页面√
/toAdd
GET
实行保存√
/employee
POST
跳转到更新数据页面√
/employee/2
GET
实行更新√
/employee
PUT
详细功能:访问首页配置view-controller
<mvc:view-controller path="/" view-name="index"/>
创建页面
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8" > <title>Title</title></head><body><h1>首页</h1><a th:href="@{/employee}">访问员工信息</a></body></html>
查询所有员工数据
@RequestMapping(value = "/employee", method = RequestMethod.GET)public String getEmployeeList(Model model){ Collection<Employee> employeeList = employeeDao.getAll(); model.addAttribute("employeeList", employeeList); return "employee_list";}
创建employee_list.html
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Employee Info</title> <script type="text/javascript" th:src="@{/static/js/vue.js}"></script></head><body> <table border="1" cellpadding="0" cellspacing="0" style="text-align: center;" id="dataTable"> <tr> <th colspan="5">Employee Info</th> </tr> <tr> <th>id</th> <th>lastName</th> <th>email</th> <th>gender</th> <th>options(<a th:href="@{/toAdd}">add</a>)</th> </tr> <tr th:each="employee : ${employeeList}"> <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 class="deleteA" @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a> <a th:href="@{'/employee/'+${employee.id}}">update</a> </td> </tr> </table></body></html>
删除
a>创建处理delete要求办法的表单
<!-- 浸染:通过超链接掌握表单的提交,将post要求转换为delete要求 --><form id="delete_form" method="post"> <!-- HiddenHttpMethodFilter哀求:必须传输_method要求参数,并且值为终极的要求办法 --> <input type="hidden" name="_method" value="delete"/></form>
b>删除超链接绑定点击事宜
引入vue.js
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
删除超链接
<a class="deleteA" @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a>
通过vue处理点击事宜
<script type="text/javascript"> var vue = new Vue({ el:"#dataTable", methods:{ //event表示当前事宜 deleteEmployee:function (event) { //通过id获取表单标签 var delete_form = document.getElementById("delete_form"); //将触发事宜的超链接的href属性为表单的action属性赋值 delete_form.action = event.target.href; //提交表单 delete_form.submit(); //阻挡超链接的默认跳转行为 event.preventDefault(); } } });</script>
掌握器方法
@RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)public String deleteEmployee(@PathVariable("id") Integer id){ employeeDao.delete(id); return "redirect:/employee";}
跳转到添加数据页面
配置view-controller
<mvc:view-controller path="/toAdd" view-name="employee_add"></mvc:view-controller>
b>创建employee_add.html
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Add Employee</title></head><body><form th:action="@{/employee}" method="post"> lastName:<input type="text" name="lastName"><br> email:<input type="text" name="email"><br> gender:<input type="radio" name="gender" value="1">male <input type="radio" name="gender" value="0">female<br> <input type="submit" value="add"><br></form></body></html>
详细功能:实行保存
a>掌握器方法
@RequestMapping(value = "/employee", method = RequestMethod.POST)public String addEmployee(Employee employee){ employeeDao.save(employee); return "redirect:/employee";}
跳转到更新数据页面
a>修正超链接
<a th:href="@{'/employee/'+${employee.id}}">update</a>
b>掌握器方法
@RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)public String getEmployeeById(@PathVariable("id") Integer id, Model model){ Employee employee = employeeDao.get(id); model.addAttribute("employee", employee); return "employee_update";}
c>创建employee_update.html
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Update Employee</title></head><body><form th:action="@{/employee}" method="post"> <input type="hidden" name="_method" value="put"> <input type="hidden" name="id" th:value="${employee.id}"> lastName:<input type="text" name="lastName" th:value="${employee.lastName}"><br> email:<input type="text" name="email" th:value="${employee.email}"><br> <!-- th:field="${employee.gender}"可用于单选框或复选框的回显 若单选框的value和employee.gender的值同等,则添加checked="checked"属性 --> gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}">male <input type="radio" name="gender" value="0" th:field="${employee.gender}">female<br> <input type="submit" value="update"><br></form></body></html>
实行更新
a>掌握器方法
@RequestMapping(value = "/employee", method = RequestMethod.PUT)public String updateEmployee(Employee employee){ employeeDao.save(employee); return "redirect:/employee";}
9 HttpMessageConverter
HttpMessageConverter,报文信息转换器,将要求报文转换为Java工具,或将Java工具转换为相应报文
HttpMessageConverter供应了两个表明和两个类型:
@RequestBody@ResponseBodyRequestEntityResponseEntity9.1 @RequestBody@RequestBody可以获取要求体,须要在掌握器方法设置一个形参,利用@RequestBody进行标识,当前要求的要求体就会为当前表明所标识的形参赋值
<form th:action="@{/testRequestBody}" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit"></form>
@RequestMapping("/testRequestBody")public String testRequestBody(@RequestBody String requestBody){ System.out.println("requestBody:"+requestBody); return "success";}//输出结果:requestBody:username=admin&password=123456
9.2 RequestEntity
RequestEntity封装要求报文的一种类型,须要在掌握器方法的形参中设置该类型的形参,当前要求的要求报文就会赋值给该形参,可以通过getHeaders()获取要求头信息,通过getBody()获取要求体信息
@RequestMapping("/testRequestEntity")public String testRequestEntity(RequestEntity<String> requestEntity){ System.out.println("requestHeader:"+requestEntity.getHeaders()); System.out.println("requestBody:"+requestEntity.getBody()); return "success";}
输出结果:
requestHeader:[host:"localhost:8080", connection:"keep-alive", content-length:"27", cache-control:"max-age=0", sec-ch-ua:"" Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"", sec-ch-ua-mobile:"?0", upgrade-insecure-requests:"1", origin:"http://localhost:8080", user-agent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"]requestBody:username=admin&password=123
9.3 @ResponseBody
@ResponseBody表明的浸染是将controller的方法返回的工具通过适当的转换器转换为指定的格式之后,写入到response工具的body区,常日用来返回JSON数据或者是XML。须要把稳的呢,在利用此表明之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response工具输出指定格式的数据。
@RequestMapping("/login")@ResponseBodypublic User login(User user){ return user;}//User字段:userName pwd // 那么在前台吸收到的数据为:'{"userName":"xxx","pwd":"xxx"}' // 效果等同于如下代码: @RequestMapping("/login") public void login(User user, HttpServletResponse response){ response.getWriter.write(JSONObject.fromObject(user).toString());}
@ResponseBody是浸染在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一样平常在异步获取数据时利用
@ResponseBody只管即便不要用在get要求中
9.4 SpringMVC处理json@ResponseBody处理json的步骤:
1、导入jackson的依赖
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.1</version></dependency>
2、在SpringMVC的核心配置文件中开启mvc的表明驱动,此时在HandlerAdaptor中会自动装置一个转换器:MappingJackson2HttpMessageConverter,可以将相应到浏览器的Java工具转换为Json格式的字符串
<mvc:annotation-driven />
3、在处理器方法上利用@ResponseBody表明进行标识,将Java工具直接作为掌握器方法的返回值返回,就会自动转换为Json格式的字符串
@RequestMapping("/testResponseUser")@ResponseBodypublic User testResponseUser(){ return new User(1001,"admin","123456",23,"男");}
浏览器的页面中展示的结果:
{"id":1001,"username":"admin","password":"123456","age":23,"sex":"男"}
9.5 处理Ajax
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>ajax</title></head><body> <div id="app"> <a th:href="@{/testAjax}" @click="testAjax">测试ajax</a> </div> <script type="text/javascript" th:src="@{/static/js/vue.js}"></script> <script type="text/javascript" th:src="@{/static/js/axios.min.js}"></script> <script type="text/javascript"> new Vue({ el: "#app", methods: { testAjax(event){ axios({ method: "post", url: event.target.href, params: { username: "admin", password: "123456" } }).then((res)=>{ alert(res.data) }) //阻挡超链接默认跳转行为 event.preventDefault(); } } }) </script></body></html>
@PostMapping("/testAjax")@ResponseBodypublic String testAjax(){return "hello,ajax";}
10 文件上传和下载10.1 文件下载
利用ResponseEntity实现下载文件的功能
@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;}
10.2 文件上传
文件上传哀求form表单的要求办法必须为post,并且添加属性enctype="multipart/form-data"
SpringMVC中将上传的文件封装到MultipartFile工具中,通过此工具可以获取文件干系信息
1、添加依赖:
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --><dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version></dependency>
2、在SpringMVC的配置文件中添加配置:
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile工具,且必须配置id属性--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
3、掌握器方法:
@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";}
11 拦截器
SpringMVC中的拦截器用于拦截掌握器方法的实行
11.1 拦截器的配置SpringMVC中的拦截器须要实现HandlerInterceptor
@Componentpublic class FirstInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("FirstInterceptor-->preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("FirstInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("FirstInterceptor-->afterCompletion");}}
SpringMVC的拦截器必须在Spring的配置文件中进行配置:
拦截所有要求<mvc:interceptors><!--按组件名配置:把稳默认情形下容器中的组件自动变驼峰命名--> <ref bean="firstInterceptor"></ref></mvc:interceptors>
或
<mvc:interceptors> <!--按类名配置--><bean class="com.birdy.interceptor.FirstInterceptor"></bean></mvc:interceptors>
11.2 自定义拦截要求
<mvc:interceptor> <!--拦截所有要求--> <mvc:mapping path="/"/> <!--配置不拦截的要求--> <mvc:exclude-mapping path="/"/> <ref bean="firstInterceptor"></ref> </mvc:interceptor>
11.3 拦截器的三个抽象方法
SpringMVC中的拦截器有三个抽象方法:
preHandle:掌握器方法实行之前实行,其boolean类型的返回值表示是否拦截或放行返回true为放行,即调用掌握器方法;返回false表示拦截,即不调用掌握器方法postHandle:掌握器方法实行之后实行postHandle()afterComplation:处理完视图和模型数据,渲染视图完毕之后实行afterComplation()11.4 多个拦截器的实行顺序若每个拦截器的preHandle()都返回true。此时多个拦截器的实行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:
preHandle()会按照配置的顺序实行,而postHandle()和afterComplation()会按照配置的反序实行若某个拦截器的preHandle()返回了false,preHandle()返回false和它之前的拦截器的preHandle()都会实行,postHandle()都不实行,返回false的拦截器之前的拦截器的afterComplation()会实行12 非常处理器12.1 基于配置的非常处理SpringMVC供应了一个处理掌握器方法实行过程中所涌现的非常的接口:HandlerExceptionResolver
HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver
SpringMVC供应了自定义的非常处理器SimpleMappingExceptionResolver,利用办法:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- properties的键表示处理器方法实行过程中涌现的非常 properties的值表示若涌现指定非常时,设置一个新的视图名称,跳转到指定页面 --> <prop key="java.lang.ArithmeticException">error</prop> </props> </property> <!-- exceptionAttribute属性设置一个属性名,将涌现的非常信息在要求域中进行共享 --> <property name="exceptionAttribute" value="ex"></property></bean>
12.2 基于表明的非常处理
//@ControllerAdvice将当前类标识为非常处理的组件@ControllerAdvicepublic class ExceptionController { //@ExceptionHandler用于设置所标识方法处理的非常 @ExceptionHandler(ArithmeticException.class) //ex表示当前要求处理中涌现的非常工具 public String handleArithmeticException(Exception ex, Model model){ //将将非常信息放在域里共享 model.addAttribute("ex", ex); return "error"; }}
12.3 测试
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>ajax</title></head><body> <a th:href="@{/testEx}">测试非常处理</a></body></html>
涌现非常后跳转的页面
<!--error.html--><!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Title</title></head><body>涌现缺点<!--/@thymesVar id="ex" type="request"/--><p th:text="${ex}"></p></body></html>
13 表明配置SpringMVC13.1 创建初始化类,代替web.xml
在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。
Spring供应了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又会查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。
Spring3.2引入了一个便利的WebApplicationInitializer根本实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展了AbstractAnnotationConfigDispatcherServletInitializer并将其支配到Servlet3.0容器的时候,容器会自动创造它,并用它来配置Servlet高下文
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}; } / 指定DispatcherServlet的映射规则,即url-pattern @return / @Override protected String[] getServletMappings() { return new String[]{"/"}; } / 添加过滤器 @return / @Override protected Filter[] getServletFilters() { CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter(); encodingFilter.setEncoding("UTF-8"); encodingFilter.setForceRequestEncoding(true); HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter(); return new Filter[]{encodingFilter, hiddenHttpMethodFilter}; }}
13.2 Spring配置类
创建SpringConfig配置类,代替spring的配置文件
@Configurationpublic class SpringConfig {//ssm整合之后,spring的配置信息写在此类中}
13.3 SpringMVC的配置文件
创建WebConfig配置类,代替SpringMVC的配置文件
@Configuration//扫描组件@ComponentScan("com.atguigu.mvc.controller")//开启MVC表明驱动@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer { //利用默认的servlet处理静态资源 @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } //配置文件上传解析器 @Bean public CommonsMultipartResolver multipartResolver(){ return new CommonsMultipartResolver(); } //配置拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { FirstInterceptor firstInterceptor = new FirstInterceptor(); registry.addInterceptor(TestInterceptor).addPathPatterns("/"); } //配置视图掌握 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); } //配置非常映射 @Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver(); Properties prop = new Properties(); prop.setProperty("java.lang.ArithmeticException", "error"); //设置非常映射 exceptionResolver.setExceptionMappings(prop); //设置共享非常信息的键 exceptionResolver.setExceptionAttribute("ex"); resolvers.add(exceptionResolver); } //配置天生模板解析器 @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; }}
13.4 拦截器
public class TestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("TestInterceptor-->preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }}
欢迎点赞+转发+关注!
大家的支持是我分享最大的动力!
!
!