当前位置: 首页 > news >正文

好的建网站的书籍外贸网络营销实战

好的建网站的书籍,外贸网络营销实战,海珠网站建设报价,wordpress的文件SpringMVC获取请求参数 环境准备工作等均省略#xff0c;可详见快速入门#xff0c;此处只写非共有部分代码 该部分示例项目SpringMvcThree已上传至Gitee#xff0c;可自行下载 客户端请求参数的格式为#xff1a;namevaluepasswordvalue... ... 服务端想要获取请求…SpringMVC获取请求参数 环境准备工作等均省略可详见快速入门此处只写非共有部分代码 该部分示例项目SpringMvcThree已上传至Gitee可自行下载 客户端请求参数的格式为namevaluepasswordvalue... ... 服务端想要获取请求参数有时需要对数据进行封装SpringMVC可接收如下类型的参数 普通数据类型基本数据类型以及字符串类型POJO类型数组类型集合类型 获取普通数据类型 注意 Controller中的业务方法的参数名称要与请求参数的名称一致如图所示 在该截图中返回值为void代表controller控制器中的该业务方法quickMethod9不回写数据但仍然需要ResponseBody注解此时代表ResponseBody的响应体为空也就是说前端页面为空。 针对获取普通数据类型来说参数未自动映射匹配有两种方法 在pom.xml文件中添加maven插件 使用RequestParam注解 以上两种方式详见代码示例部分 代码示例 此处只写controller控制器类其余部分搭建可详见快速入门以及数据响应部分内容 在controller包下创建UserController类代码如下 //将Usercontroller放到Spring容器中 Controller RequestMapping(/user) public class UserController {ResponseBodyRequestMapping(value /quick1)public void save1(String username, int age) {System.out.println(name name);System.out.println(age: age);} }此时运行截图如下会报错 报错原因错误说明 Spring MVC 无法推断参数名称通常是因为编译时没有启用参数名的保留功能或者方法参数缺少显式绑定的注解 解决方法 方案一 启用参数名的保留功能即在pom.xml文件中加上maven插件插件代码如下 plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactId!-- maven插件版本 --version3.13.0/version configuration!-- 所使用的Java版本 --source21/source target21/targetcompilerArgsarg-parameters/arg/compilerArgs/configuration /plugin方案二 为方法参数添加 RequestParam 注解明确指定参数名称更改后的UserController类代码如下 注意获取普通数据类型的参数以方案二为准以此来避免影响后续获取其它类型参数的示例操作即以pom.xml文件中未添加maven插件来演示后续获取各种类型的请求参数的操作以此来证明其它类型均可自动映射匹配 //将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {RequestMapping(value quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);} }此时运行结果如下 GET请求运行后前端页面为空白但是控制台会有输出如图所示 POST请求运行后前端页面为空白但是控制台会有输出如图所示 获取POJO类型 注意 Controller中业务方法的参数为pojo类对象且该pojo类中的的属性名要与请求参数的名称一致如图所示 获取POJO类型时不需要去添加maven插件或使用RequestParam注解来使参数自动映射匹配在本代码示例中的获取普通数据类型使用的是注解方式来进行参数匹配以此来区别说明POJO类型不需要去添加maven插件或使用RequestParam注解。 获取普通POJO类型代码示例 创建pojo包并在该包下创建一个User类代码如下 package at.guigu.pojo;public class User {private String name;private int age;public User() {}public User(String name, int age) {this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return User{ name name \ , age age };} }在controller包下的UserController类中添加save2方法完整代码如下 package at.guigu.controller;import at.guigu.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通pojo类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);} }获取嵌套POJO类型代码示例 在pojo包中创建Address类、Brand类并将其嵌套在Brand类中此时Brand类及Address类简要代码如下 public class Brand {private String brandName;private int brandPrice;private Address address;...... } public class Address {private String province;private String city;...... }在controller包下的UserController类中添加save22方法完整代码如下 package at.guigu.controller;import at.guigu.pojo.Brand; import at.guigu.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通pojo类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);} }获取JSON对象的POJO类型 定义前端传递的是JSON对象 在controller包下的UserController类中添加save222方法完整代码如下 传递JSON对象时参数需加上RequestBody注解 package at.guigu.controller;import at.guigu.pojo.Brand; import at.guigu.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通pojo类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);}// 获取JSON对象的POJO类型ResponseBodyRequestMapping(/quick222)public void save222(RequestBody User user) throws IOException {System.out.println(user);} }获取数组类型 注意 Controller中业务方法的参数的数组名称要与请求参数的名称一致如图所示 针对获取数组类型来说参数未自动映射匹配有两种方法 在pom.xml文件中添加maven插件 使用RequestParam注解 以上两种方法的操作与获取获取普通数据类型一致可详见获取普通数据类型部分的代码示例此处仅以注解形式示例 代码示例 在controller包下的UserController类中添加save3方法完整代码如下 package at.guigu.controller;import at.guigu.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Arrays;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通POJO类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);}// 获取JSON对象的POJO类型ResponseBodyRequestMapping(/quick222)public void save222(RequestBody User user) throws IOException {System.out.println(user);}// 获取数组类型ResponseBodyRequestMapping(/quick3)public void save3(RequestParam(strs)String[] strs) throws IOException {// 由于直接打印数组时只会打印出其地址所以将其转为List集合输出到控制台System.out.println(Arrays.asList(strs));} }获取集合类型—集合保存pojo类的对象 获取普通集合类型 在controller包下的UserController类中添加savepre4方法代码如下 package at.guigu.controller;import at.guigu.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Arrays;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通POJO类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);}// 获取JSON对象的POJO类型ResponseBodyRequestMapping(/quick222)public void save222(RequestBody User user) throws IOException {System.out.println(user);}// 获取数组类型ResponseBodyRequestMapping(/quick3)public void save3(RequestParam(strs)String[] strs) throws IOException {// 由于直接打印数组时只会打印出其地址所以将其转为List集合输出到控制台System.out.println(Arrays.asList(strs));}// 获取普通集合类型ResponseBodyRequestMapping(/quickpre4)public void savepre4(RequestParam(strs) ListString strs) throws IOException {System.out.println(strs);} }针对获取数组类型来说参数未自动映射匹配有两种方法 在pom.xml文件中添加maven插件 使用RequestParam注解 以上两种方法的操作与获取获取普通数据类型一致可详见获取普通数据类型部分的代码示例此处仅以注解形式示例 获取JSON集合类型 在controller包下的UserController类中添加savepre4方法代码如下 获取数组集合类型的参数需要用RequestBody注解修饰 package at.guigu.controller;import at.guigu.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Arrays;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通POJO类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);}// 获取JSON对象的POJO类型ResponseBodyRequestMapping(/quick222)public void save222(RequestBody User user) throws IOException {System.out.println(user);}// 获取数组类型ResponseBodyRequestMapping(/quick3)public void save3(RequestParam(strs)String[] strs) throws IOException {// 由于直接打印数组时只会打印出其地址所以将其转为List集合输出到控制台System.out.println(Arrays.asList(strs));}// 获取普通集合类型ResponseBodyRequestMapping(/quickpre4)public void savepre4(RequestParam(strs) ListString strs) throws IOException {System.out.println(strs);}// 获取JSON集合类型ResponseBodyRequestMapping(/quickpre44)public void savepre44(RequestBody ListString strs) throws IOException {System.out.println(strs);} }获取对象集合类型 有三种获取方式 使用POJO类进行集合封装然后获取集合类型的请求参数不使用POJO类进行集合封装 方式一使用POJO类进行集合封装 注意 获取集合参数时要将集合参数封装到一个POJO类中才可以也就是说集合要封装到一个对象中一般定义为VO类作为这个对象里面的私有属性存在.此时就相当于获取POJO类型详见代码示例 代码示例 Step1POJO类中创建User类代码详见获取POJO类型创建VO类代码如下 package at.guigu.pojo;import java.util.List;public class VO {// 将想要获取的集合封装到对象中private ListUser userList;public ListUser getUserList() {return userList;}public void setUserList(ListUser userList) {this.userList userList;}Overridepublic String toString() {return VO{ userList userList };} }Step2在controller包下的UserController类中添加save4方法完整代码如下 package at.guigu.controller; import at.guigu.pojo.User; import at.guigu.pojo.VO; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Arrays;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通POJO类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);}// 获取JSON对象的POJO类型ResponseBodyRequestMapping(/quick222)public void save222(RequestBody User user) throws IOException {System.out.println(user);}// 获取数组类型ResponseBodyRequestMapping(/quick3)public void save3(RequestParam(strs)String[] strs) throws IOException {// 由于直接打印数组时只会打印出其地址所以将其转为List集合输出到控制台System.out.println(Arrays.asList(strs));}// 获取普通集合类型ResponseBodyRequestMapping(/quickpre4)public void savepre4(RequestParam(strs) ListString strs) throws IOException {System.out.println(strs);}// 获取JSON集合类型ResponseBodyRequestMapping(/quickpre44)public void savepre44(RequestBody ListString strs) throws IOException {System.out.println(strs);}// 获取对象集合类型方式一ResponseBodyRequestMapping(/quick4)public void save4(VO vo) throws IOException {System.out.println(vo);} }此时相等于获取POJO类型所以请求参数名称要与该POJO类即VO类中的属性名一致而在VO类中该属性userList为一个集合所以不仅要与userList一致更要进一步与该集合里面存储的对象User的属性名样一致 Step3以页面为例post方式提交web项目核心目录即webapp下创建一个form.jsp页面代码如下 % page contentTypetext/html;charsetUTF-8 languagejava % htmlheadtitleTitle/title/headbody%--将表单提交到控制器映射地址下的/user/quick4也就是UserController类下的save4业务方法中--%form action/SpringMvcThree/user/quick4 methodpost%--将第一个请求参数提交到userList集合中第一个元素的name属性中--%input typetext nameuserList[0].namebr/%--将第一个请求参数提交到userList集合中第二个元素的age属性中--%input typetext nameuserList[0].agebr/input typetext nameuserList[0].namebr/input typetext nameuserList[0].agebr/input typesubmit value提交/form/body /html注意因为请求参数名称要与VO类中的集合属性名一致又因为集合中存储的是POJO类对象即User而User类中有两个属性name和age所以请求参数名称要与集合名.POJO类属性名一致所以表单中name属性值为userList[0].name它的含义就是集合中第一个元素的name属性。 运行后截图如下所示 方式二前端使用JSON数据发送集合 注意 当使用ajax提交表单时可以指定contentType为json形式然后在对应业务方法的参数位置使用RequestBody注解就可以直接接收集合数据而不需要使用POJO进行封装 代码示例 Step1在web项目核心目录即webapp下创建js目录引入jquery源码文件jquery-3.7.1.js官网自行下载 Step2web项目核心目录即webapp下创建一个ajax.jsp文件并在该文件中引入jquery的源码文件最终代码如下 %--Created by IntelliJ IDEA.User: 10195Date: 2024/11/22Time: 16:04To change this template use File | Settings | File Templates. --% % page contentTypetext/html;charsetUTF-8 languagejava % htmlheadtitleTitle/title/headbodyscript srcjs/jquery-3.7.1.js/scriptscript// 创建核心对象var userList new Array();userList.push({name:zhangsna, age:15});userList.push({name:lisi, age:16});$.ajax({type:POST,url:user/quick5,data:JSON.stringify(userList),contentType:application/json;charsetutf-8});/script/body /htmlStep3在springMVC的核心配置文件中添加如下代码: 原因在SpringMVC中默认会拦截对所有资源的请求包括静态资源若不单独配置则会使静态资源请求被误认为是需要交给核心前端控制器处理的业务请求此时由于前端控制器无法找到与之对应的业务方法从而导致资源无法正确加载所以需要在SpringMVC的核心配置文件中对这些资源进行开放访问。 !--配置静态资源的路径映射开放某些资源的访问-- mvc:resources mapping/js/** location/js//springMVC的核心配置文件完整代码如下 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://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!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/--property nameprefix value/user//property!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--mvc的注解驱动--mvc:annotation-driven/!--等同于配置处理器适配器--!--bean idhandlerAdapter classorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterproperty namemessageConverterslistbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter//list/property/bean--mvc:resources mapping/js/** location/js// /beansStep4在controller包下的UserController类中添加save5方法完整代码如下 package at.guigu.controller;import at.guigu.pojo.User; import at.guigu.pojo.VO; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Arrays; import java.util.List;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取普通POJO类型ResponseBodyRequestMapping(/quick2)public void save2(User user) throws IOException {System.out.println(user);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);}// 获取JSON对象的POJO类型ResponseBodyRequestMapping(/quick222)public void save222(RequestBody User user) throws IOException {System.out.println(user);}// 获取数组类型ResponseBodyRequestMapping(/quick3)public void save3(RequestParam(strs)String[] strs) throws IOException {// 由于直接打印数组时只会打印出其地址所以将其转为List集合输出到控制台System.out.println(Arrays.asList(strs));}// 获取普通集合类型ResponseBodyRequestMapping(/quickpre4)public void savepre4(RequestParam(strs) ListString strs) throws IOException {System.out.println(strs);}// 获取JSON集合类型ResponseBodyRequestMapping(/quickpre44)public void savepre44(RequestBody ListString strs) throws IOException {System.out.println(strs);}// 获取对象集合类型方式一ResponseBodyRequestMapping(/quick4)public void save4(VO vo) throws IOException {System.out.println(vo);}// 获取对象集合类型方式二ResponseBodyRequestMapping(/quick5)public void save5(RequestBody ListUser userList) throws IOException {System.out.println(userList);} }开放静态资源的请求访问SpringMVC配置文件形式 注意 在SpringMVC中默认会拦截对所有资源的请求包括静态资源若不单独配置则会使静态资源请求被误认为是需要交给核心前端控制器处理的业务请求此时由于前端控制器无法找到与之对应的业务方法从而导致资源无法正确加载所以需要在SpringMVC的核心配置文件中对这些资源进行开放访问。开放静态资源的请求访问时其路径映射不能与内部资源视图解析器一样否则会报错 通过mvc:resources标签进行资源路径配置标签常用属性如下 mvc:resources标签属性解释mapping告诉 Spring MVC当用户请求某些特定 URL 时这些请求是访问静态资源而不是交给控制器处理。/js/**代表js后可以是多级url地址location定义资源在服务器上的实际存放位置 由于每开放一种静态资源就要写一个该标签代码所以可用如下代码代替 mvc:default-servlet-handler/解释 在SpringMVC中默认会拦截对所有资源的请求包括静态资源若不单独配置则会使静态资源请求被误认为是需要交给核心前端控制器处理的业务请求此时由于前端控制器无法找到与之对应的业务方法从而导致资源无法正确加载此时就会交由Tomcat来找对应的静态资源从而使得资源正确加载 简要总结 SpringMVC框架无法找到对应资源时就会让原始容器Tomcat去找静态资源 开放对图片、jquery文件等静态资源访问的代码示例如下 !--配置静态资源的路径映射开放某些资源的访问-- mvc:resources mapping/js/** location/js// mvc:resources mapping/img/** location/img//等同于 mvc:default-servlet-handler/开放静态资源的请求访问方式一SpringMVC类形式 Step1在config包下创建一个继承WebMvcConfigurationSupport的子类SpringMvcSupport并为其加上Configuration注解代码如下 package at.guigu.config;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;// 静态资源的路径映射类 Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport {Overrideprotected void addResourceHandlers (ResourceHandlerRegistry registry) {// 当访问/pages/????时候从/pages目录下查找内容// 配置静态资源的路径映射开放某些资源的访问// 等同于mvc:resources mapping/js/** location/js//registry.addResourceHandler(/xxx/**).addResourceLocations(/xxx/);// 等同于mvc:resources mapping/img/** location/img//registry.addResourceHandler(/img/**).addResourceLocations(/img/);} }Step2 在SpringMVC核心配置类中用ComponentScan注解扫描静态资源的路径映射类所在包代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan({at.guigu.controller, at.guigu.config}) // 自动配置 Spring MVC 的各种特性,比如类型转换器、mvc的注解驱动mvc:annotation-driven/、静态资源路径映射 EnableWebMvc public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/user/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;} }开放静态资源的请求访问方式二SpringMVC类形式 让SpringMVC的核心配置类SpringMvcConfiguration实现WebMvcConfigurer接口然后重写其中的addResourceHandlers方法即可代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan(at.guigu.controller) // 自动配置 Spring MVC 的各种特性 EnableWebMvc public class SpringMvcConfiguration implements WebMvcConfigurer {// 依赖注入拦截器的beanAutowiredprivate MyInterceptor myInterceptor;// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/jsp/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;}// 配置静态资源路径Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 配置静态资源路径映射registry.addResourceHandler(/xxx/**).addResourceLocations(/xxx/);} }GET请求参数乱码问题 Tomcat8.5版本之前会出现GET请求参数乱码问题在其之后官方就已经给解决了 若使用的是Tomcat7插件则会出现Get请求参数乱码问题此时需要在pom.xml文件对应的Tomcat插件中配置UTF-8字符集插件代码如下 plugins!-- Tomcat插件 --plugingroupIdorg.apache.tomcat.maven/groupIdartifactIdtomcat7-maven-plugin/artifactIdversion2.2/versionconfigurationport80/port!--Tomcat端口号--path//path!--虚拟目录--uriEncodingUTF-8/uriEncoding!--指定字符集--/configuration/plugin /pluginsPOST请求参数乱码问题 SpringMVC配置文件形式 当使用POST请求时数据会出现乱码问题可详见使用POJO类进行集合封装的代码示例解决方法 在web项目核心目录即webapp下的WEB-INF中的web.xml中配置一个全局过滤器来进行编码的过滤代码如下 注意filter以及filter-mapping标签需要写到linstener标签前因为web.xml中有严格的标签顺序 !--全局过滤器-- filterfilter-nameCharacterEncodingFilter/filter-namefilter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-classinit-paramparam-nameencoding/param-nameparam-valueUTF-8/param-value/init-param /filter filter-mappingfilter-nameCharacterEncodingFilter/filter-nameurl-pattern/*/url-pattern /filter-mapping此时再次运行使用POJO类进行集合封装的代码示例后就不会出现乱码问题了运行截图如下 SpringMVC配置类形式 当使用POST请求时数据会出现乱码问题可详见使用POJO类进行集合封装的代码示例解决方法 在web.xml文件对应的配置类中指定字符过滤器代码如下 package at.guigu.config;import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;import javax.servlet.Filter;// 定义一个Servlet容器启动的配置类来加载Spring的配置 public class ServletContainerInitConfiguration extends AbstractAnnotationConfigDispatcherServletInitializer {// 加载SpringMVC的配置Overrideprotected Class?[] getServletConfigClasses() {return new Class[]{SpringMvcConfiguration.class};}// 设置哪些请求归SpringMVC处理Overrideprotected String[] getServletMappings() {return new String[]{/};}// 加载非SringMVC的配置比如加载Spring的配置Overrideprotected Class?[] getRootConfigClasses() {return new Class[]{SpringConfiguration.class};}// POST请求乱码处理指定字符过滤器Overrideprotected Filter[] getServletFilters() {CharacterEncodingFilter filter new CharacterEncodingFilter();filter.setEncoding(UTF-8);return new Filter[]{filter};} }/* 等同于 // 定义一个Servlet容器启动的配置类来加载Spring的配置 public class ServletContainerInitConfiguration extends AbstractDispatcherServletInitializer {// 加载SpringMVC的配置Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext context new AnnotationConfigWebApplicationContext();context.register(SpringMvcConfiguration.class);return context;}// 设置哪些请求归SpringMVC处理Overrideprotected String[] getServletMappings() {// 代表将所有请求都交给前端控制器处理return new String[]{/};}// 加载非SringMVC的配置比如加载Spring的配置Overrideprotected WebApplicationContext createRootApplicationContext() {AnnotationConfigWebApplicationContext context new AnnotationConfigWebApplicationContext();context.register(SpringConfiguration.class);return context;}// POST请求乱码处理指定字符过滤器Overrideprotected Filter[] getServletFilters() {CharacterEncodingFilter filter new CharacterEncodingFilter();filter.setEncoding(UTF-8);return new Filter[]{filter};} }*/ requestParam注解 requestParam注解属性解释value请求参数的名称required该注解指定的请求参数是否必须存在默认为true提交时若该参数不存在则会报错defaultValue当该注解没有指定请求参数时则使用指定默认值 定义当请求参数的名称与Controller控制器中对应的业务方法的参数名称不一致时将它们显式的绑定到一块 代码示例如下 在controller包下的UserController类中添加save6方法完整代码如下 package at.guigu.controller; import at.guigu.pojo.User; import at.guigu.pojo.VO; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Arrays; import java.util.List;//将Usercontroller放到Spring容器中 Controller RequestMapping(value /user) public class UserController {// 获取普通数据类型RequestMapping(value /quick1)ResponseBodypublic void save1(RequestParam(username)String username, RequestParam(age)int age) throws IOException {System.out.println(username);System.out.println(age);}// 获取嵌套POJO类型ResponseBodyRequestMapping(/quick22)public void save22(Brand brand) throws IOException {System.out.println(brand);}// 获取JSON对象的POJO类型ResponseBodyRequestMapping(/quick222)public void save222(RequestBody User user) throws IOException {System.out.println(user);}// 获取数组类型ResponseBodyRequestMapping(/quick3)public void save3(RequestParam(strs)String[] strs) throws IOException {// 由于直接打印数组时只会打印出其地址所以将其转为List集合输出到控制台System.out.println(Arrays.asList(strs));}// 获取普通集合类型ResponseBodyRequestMapping(/quickpre4)public void savepre4(RequestParam(strs) ListString strs) throws IOException {System.out.println(strs);}// 获取JSON集合类型ResponseBodyRequestMapping(/quickpre44)public void savepre44(RequestBody ListString strs) throws IOException {System.out.println(strs);}// 获取对象集合类型方式一ResponseBodyRequestMapping(/quick4)public void save4(VO vo) throws IOException {System.out.println(vo);}// 获取对象集合类型方式二ResponseBodyRequestMapping(/quick5)public void save5(RequestBody ListUser userList) throws IOException {System.out.println(userList);}// 测试RequestParam注解RequestMapping(value /quick1)ResponseBodypublic void save6(RequestParam(value name, required false, defaultValue zhangzhang)String username) throws IOException {System.out.println(username);} }请求参数名与业务方法的参数名不一致 不写请求参数则会将指定默认值赋值给业务方法对应的参数 自定义类型转换器 SpringMVC默认已经提供了一些常用的类型转换器比如将客户端提交的字符串转换成int类型进行参数设置。但不是所有是数据类型都提供了转换器比如日期类型的数据此时就需要自定义转换器 注意 参数若不会自动映射匹配所以可使用如下两种方法 使用RequestParam注解在pom.xml文件中添加maven插件以上两种方式代码示例详见获取普通数据类型 日期类型参数传递示例一SpringMVC配置文件形式 本代码示例以日期类型为例将日期封装为yyyy-MM-dd形式 注意日期默认封装格式为yyyy/MM/dd形式若请求参数中为yyyy-MM-dd形式则会报错所以本示例是将其转换为常用的yyyy-MM-dd形式 开发步骤 自定义一个实现Converter接口的转换器类 在SpringMVC的核心配置文件中声明转换器类 在核心配置文件中用annotation-driven即mvc的注解驱动标签中的conversion-service属性引用转换器类 Step1 创建一个与三层架构包同级的converter包然后定义一个实现Converter接口的类DataConverter并定义该类的泛型为String, Date然后重写其中的convert方法在该方法中将日期转换成指定格式的日期对象并返回 注意 该接口是org.springframework.core.convert.converter.Converter包下的String, Date中第一个参数String为请求参数字符串第二个参数Date为要转换到的类型convert方法的参数为客户端的请求参数 package at.guigu.converter;import org.springframework.core.convert.converter.Converter;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public class DataConverter implements ConverterString, Date {Overridepublic Date convert(String source) {// 将日期字符串转换成指定的日期对象并返回SimpleDateFormat format new SimpleDateFormat(yyyy-MM-dd);Date date null;try {date format.parse(source);} catch (ParseException e) {e.printStackTrace();}return date;} }Step2 在SpringMVC的核心配置文件中声明转换器类核心配置文件代码如下 !--声明转换器类-- bean idconversionService classorg.springframework.context.support.ConversionServiceFactoryBeanproperty nameconverterslistbean classat.guigu.converter.DataConverter/bean/list/property /beanStep3 在SpringMVC的核心配置文件中用annotation-driven标签中的conversion-service属性引用转换器类的id代码如下 mvc:annotation-driven conversion-serviceconversionService/SpringMVC的核心配置文件代码如下 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://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!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/--property nameprefix value/user//property!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--mvc的注解驱动--!--利用conversion-service来引用转换器类属性值为转换器对应的id--mvc:annotation-driven conversion-serviceconversionService/!--等同于配置处理器适配器--!--bean idhandlerAdapter classorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterproperty namemessageConverterslistbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter//list/property/bean--!--配置静态资源的路径映射让 Spring MVC 可以处理静态文件--mvc:default-servlet-handler/!--声明转换器类--bean idconversionService classorg.springframework.context.support.ConversionServiceFactoryBeanproperty nameconverterslistbean classat.guigu.converter.DataConverter/bean/list/property/bean /beansStep4 在controller包下创建UserControllerThree类并添加save1方法完整代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Date;Controller RequestMapping(/user3) public class UserControllerThree {ResponseBodyRequestMapping(/quickk1)public void save1(RequestParam(date) Date date) throws IOException {System.out.println(date);} }运行截图如下 日期类型参数传递示例二SpringMVC配置类形式 日期类型数据基于系统不同格式也不尽相同所以我们在接收形参时可以根据不同的日期格式设置不同的接收方式 2088-08-18 2088/08/18 08/18/2088 注意日期类型参数传递除了使用自定义类型转换器外详见自定义类型转换器中的内容还可以使用注解形式步骤如下 在控制器给对应方法的形参加上DateTimeFormat(pattern)注解 它内部依赖的是Converter接口 在SpringMVC的核心配置类上加上EnableWebMvc注解它可以根据类型匹配对应的类型转换器代替了SpringMVC配置文件形式中的一下两步 在SpringMVC的核心配置文件中声明转换器类 在核心配置文件中用annotation-driven即mvc的注解驱动标签中的conversion-service属性引用转换器类 Step1 在MvcReqClaDemo项目示例中的controller包下创建UserControllerThree类并添加save1方法完整代码如下 package at.guigu.controller;import org.springframework.format.annotation.DateTimeFormat; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;import java.io.IOException; import java.util.Date;// 自定义类型转换器 Controller RequestMapping(/user3) public class UserControllerThree {ResponseBodyRequestMapping(/quickk1)public void save1(RequestParam(date) Date date,DateTimeFormat(pattern yyyy-MM-dd) RequestParam(date1) Date date1,DateTimeFormat(pattern yyyy-MM-dd HH:mm:ss) RequestParam(date2) Date date2) throws IOException {System.out.println(date);System.out.println(date1);System.out.println(date2);} }Step2 SpringMVC核心类添加上EnableWebMvc注解代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan(at.guigu.controller) // 自动配置 Spring MVC 的各种特性,比如类型转换器、mvc的注解驱动mvc:annotation-driven/ EnableWebMvc public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/user/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;} }获取Servlet的相关API SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入常用对象有 HttpServletRequestHttpServletResponseHttpSession 获取方式 只需要将想要的Servlet的API作为控制器对应方法的参数即可 方法一般是谁调用谁传参因为业务方法是SpringMVC框架调用的所以SpringMVC会自动根据方法的参数进行注入 测试示例 在controller包下创建UserControllerFour类并添加save1方法完整代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;Controller RequestMapping(/user4) public class UserControllerFour {ResponseBodyRequestMapping(/quick1)public void save1(HttpServletRequest req, HttpServletResponse res, HttpSession hs) throws Exception{System.out.println(req);System.out.println(res);System.out.println(hs);} }获取请求头信息 利用RequestHeader注解来获取请求头信息相当于web阶段所学的request.getHeader(name)方法可详见会话跟踪技术部分内容 RequestHeader注解属性解释value请求头名称required是否必须携带该请求头默认为true即必须携带该请求头才能访问这个资源 测试示例 在controller包下创建UserControllerFive类并添加save1方法代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;Controller RequestMapping(/user5) public class UserControllerFive {ResponseBodyRequestMapping(/quick1)public void save1() throws Exception{} }运行后通过开发者工具可看到请求头信息如图所示 假设现在获取请求头user-agent的信息则代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;Controller RequestMapping(/user5) public class UserControllerFive {ResponseBodyRequestMapping(/quick1)public void save1(RequestHeader(value User-Agent, required false) String user_agent) throws Exception{System.out.println(user_agent);} }获取指定Cookie请求头信息 RequestHeader只能根据如图所示1中的请求头来获取2中的信息而有些请求头后的信息有键值对比如Cookie中又有很多键值对Cookie此时若想获取Cookie里面的小Cookie的话RequestHeader注解就会失效。 Cookie不只有一个所以属于特殊请求头如图所示 CookieValue获取指定Cookie的值 CookieValue注解属性解释valueCookie名称required是否必须携带该Cookie默认为true即必须携带该Cookie才能访问这个资源 代码示例此处以JSESSIONID这个Cookie为例 在UserControllerFive类中添加save2方法代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;Controller RequestMapping(/user5) public class UserControllerFive {// 获取普通请求头ResponseBodyRequestMapping(/quick1)public void save1(RequestHeader(value User-Agent, required false) String user_agent) throws Exception{System.out.println(user_agent);}// 获取特殊请求头获取指定CookieResponseBodyRequestMapping(/quick2)public void save2(CookieValue(value JSESSIONID, required false) String jessionid) throws Exception{System.out.println(jessionid);} }注意除以上注解之外也可使用通用方式即使用HttpServletRequest接口中的方法来获取请求头信息可详见会话跟踪技术部分内容 文件上传获取文件 文件上传客户端三要素 表单项typefile表单提交方式为post表单的enctype属性是多部分表单形式即enctypemulipart/form-data 注意 当form表单修改为多部分表单时request.getParameter(String name)会失效因为该方法只能获取单个参数值 该方法是根据键名来获取参数值具体解释可详见可见WebHttpServletRequestResponse部分内容 默认情况下enctypeapplication/x-www-form-urlencoded此时form表单的正文内容是keyvaluekeyvaluekeyvalue 当enctypemulipart/form-data时请求正文内容就会变成多部分形式此时能够获取表单的所有数据如图所示 文件上传步骤 在pom.xml文件中导入坐标fileupload和io两个坐标 !--fileupload坐标-- dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.5/version /dependency!--io坐标-- dependencygroupIdcommons-io/groupIdartifactIdcommons-io/artifactIdversion2.17.0/version /dependency在SpringMVC的核心配置文件中配置文件上传解析器 编写文件上传代码 单文件上传和多文件上传的公共步骤(后续代码演示不在演示公共步骤) 在pom.xml文件中导入fileupload和io两个坐标文件完整代码如下 project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.example/groupIdartifactIdSpringMvcDemo/artifactIdversion1.0-SNAPSHOT/version/parentartifactIdSpringMvcThree/artifactIdpackagingwar/packagingnameSpringMvcThree Maven Webapp/nameurlhttp://maven.apache.org/urldependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope/dependency!--Spring相关坐标--!--spring坐标--dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion6.1.6/version/dependency!--spring-web --dependencygroupIdorg.springframework/groupIdartifactIdspring-web/artifactIdversion5.2.25.RELEASE/version/dependency!--spring-test坐标--dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion6.1.6/versionscopetest/scope/dependency!--Annotation坐标--dependencygroupIdjavax.annotation/groupIdartifactIdjavax.annotation-api/artifactIdversion1.3.2/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.2/versionscopetest/scope/dependency!-- servlet--dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion4.0.1/versionscopeprovided/scope/dependency!--jsp--dependencygroupIdjavax.servlet.jsp/groupIdartifactIdjavax.servlet.jsp-api/artifactIdversion2.3.3/versionscopeprovided/scope/dependency!--SpringMVC相关坐标--!--spring-webmvc--dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.2.25.RELEASE/version/dependency!--jackson-core--dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-core/artifactIdversion2.17.1/version/dependency!--jackson-databind--dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.17.1/version/dependency!--jackson-annotations--dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-annotations/artifactIdversion2.17.1/version/dependency!--数据库相关坐标--!--mysql坐标--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.33/version/dependency!--druid坐标--dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.18/version/dependency!--c3p0坐标--dependencygroupIdcom.mchange/groupIdartifactIdc3p0/artifactIdversion0.9.5.5/version/dependency!--MyBatis相关坐标--!--spring-jdbc--dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion6.1.10/version/dependency!--mybatis-spring--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion3.0.3/version/dependency!--MyBatis坐标--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.16/version/dependency!--文件上传相关坐标--!--fileupload坐标--dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.5/version/dependency!--io坐标--dependencygroupIdcommons-io/groupIdartifactIdcommons-io/artifactIdversion2.17.0/version/dependency/dependenciesbuildfinalNameSpringMvcThree/finalNameplugins!-- Tomcat插件 --plugingroupIdorg.apache.tomcat.maven/groupIdartifactIdtomcat7-maven-plugin/artifactIdversion2.2/version/plugin!--plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdlt;!ndash; maven插件版本 ndash;gt;version3.13.0/versionconfigurationlt;!ndash; Java版本 ndash;gt;source21/sourcecompilerArgsarg-parameters/arg/compilerArgs/configuration/plugin--/plugins/build /project在SpringMVC的核心配置文件中配置文件上传解析器代码如下 SpringMVC核心配置文件代码如下 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://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!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的前缀属性prefix的值设为/jsp/--property nameprefix value/user//property!--将InternalResourceViewResolver类中的前缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--mvc的注解驱动--mvc:annotation-driven conversion-serviceconversionService/!--等同于配置处理器适配器--!--bean idhandlerAdapter classorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterproperty namemessageConverterslistbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter//list/property/bean--!--配置静态资源的路径映射让 Spring MVC 可以处理静态文件--mvc:default-servlet-handler/!--声明转换器类--bean idconversionService classorg.springframework.context.support.ConversionServiceFactoryBeanproperty nameconverterslistbean classat.guigu.converter.DataConverter/bean/list/property/bean!--配置文件上传解析器--bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver!--所上传文件的编码类型--property namedefaultEncoding valueUTF-8/!--所上传的单个文件的大小--property namemaxUploadSizePerFile value500000/!--所上传的总文件的大小--property namemaxUploadSize value5000000//bean /beansSpringMVC核心配置文件对应的核心配置类代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan(at.guigu.controller) // 自动配置 Spring MVC 的各种特性,比如类型转换器、mvc的注解驱动mvc:annotation-driven/、静态资源路径映射 EnableWebMvc // 引入配置静态资源的路径映射类 Import(SpringMvcSupport.class) public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/user/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;}// 配置文件上传解析器Beanpublic CommonsMultipartResolver multipartResolver() {CommonsMultipartResolver resolver new CommonsMultipartResolver();resolver.setDefaultEncoding(UTF-8); // 所上传文件的编码类型resolver.setMaxUploadSizePerFile(500000);// 所上传的单个文件的大小resolver.setMaxUploadSize(5000000);// 所上传的总文件的大小return resolver;} }单文件上传示例 在web项目核心目录即webapp下创建文件upload.jsp文件代码如下 % page contentTypetext/html;charsetUTF-8 languagejava % htmlheadtitleTitle/title/headbodyform action/SpringMvcThree/user6/quick1 methodpost enctypemultipart/form-data名称input typetext name usernamebr/文件input typefile name uploadFilebr/input typesubmit value提交br//form/body /html在controller包下创建UserControllerSix类并添加save1方法完整代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile;import java.io.File; import java.io.IOException;Controller RequestMapping(/user6) public class UserControllerSix {ResponseBodyRequestMapping(/quick1)public void save1(RequestParam(username) String username, RequestParam(uploadFile) MultipartFile uploadFile) throws IOException {System.out.println(username);System.out.println(uploadFile);// 获取上传文件名String originalFilename uploadFile.getOriginalFilename();// 保存文件uploadFile.transferTo(new File(F:\\node\\idea\\test\\ originalFilename));} }注意 业务方法的参数名要与请求参数名一致由于表单上传的文件会被SpringMVC封装成一个MultipartFile对象且对象名为表单中所定义的文件的name属性值所以对应业务方法中第二个参数的名为uploadFile 单文件上传时参数不会自动映射匹配解决方法有两种 在pom.xml文件中添加maven插件 使用RequestParam注解 以上两种方式详见获取普通数据类型的代码示例部分 多文件上传示例 方式一文件name属性的属性名不一样 在web项目核心目录即webapp下创建文件upload2.jsp文件代码如下 % page contentTypetext/html;charsetUTF-8 languagejava % htmlheadtitleTitle/title/headbodyform action/SpringMvcThree/user6/quick2 methodpost enctypemultipart/form-data名称input typetext name usernamebr/文件1input typefile name uploadFile1br/文件2input typefile name uploadFile2br/input typesubmit value提交br//form/body /html在UserControllerSix类中添加save2方法完整代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile;import java.io.File; import java.io.IOException;Controller RequestMapping(/user6) public class UserControllerSix {// 单文件上传ResponseBodyRequestMapping(/quick1)public void save1(RequestParam(username) String username, RequestParam(uploadFile) MultipartFile uploadFile) throws IOException {System.out.println(username);System.out.println(uploadFile);// 获取上传文件名String originalFilename uploadFile.getOriginalFilename();// 保存文件uploadFile.transferTo(new File(F:\\node\\idea\\test\\ originalFilename));}//多文件上传 方式一ResponseBodyRequestMapping(/quick2)public void save2(RequestParam(username) String username, RequestParam(uploadFile1) MultipartFile uploadFile1, RequestParam(uploadFile2) MultipartFile uploadFile2) throws IOException {System.out.println(username);System.out.println(uploadFile1);System.out.println(uploadFile2);// 获取上传文件1的文件名String originalFilename1 uploadFile1.getOriginalFilename();// 保存文件1uploadFile1.transferTo(new File(F:\\node\\idea\\test\\ originalFilename1));// 获取上传文件2的文件名String originalFilename2 uploadFile2.getOriginalFilename();// 保存文件2uploadFile2.transferTo(new File(F:\\node\\idea\\test\\ originalFilename2));} }方式二文件name属性的属性名一样此时用MultipartFile对象数组 在web项目核心目录即webapp下创建文件upload3.jsp文件代码如下 % page contentTypetext/html;charsetUTF-8 languagejava % htmlheadtitleTitle/title/headbodyform action/SpringMvcThree/user6/quick3 methodpost enctypemultipart/form-data名称input typetext name usernamebr/文件1input typefile name uploadFilesbr/文件2input typefile name uploadFilesbr/input typesubmit value提交br//form/body /html在UserControllerSix类中添加save2方法完整代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile;import java.io.File; import java.io.IOException;Controller RequestMapping(/user6) public class UserControllerSix {// 单文件上传ResponseBodyRequestMapping(/quick1)public void save1(RequestParam(username) String username, RequestParam(uploadFile) MultipartFile uploadFile) throws IOException {System.out.println(username);System.out.println(uploadFile);// 获取上传文件名String originalFilename uploadFile.getOriginalFilename();// 保存文件uploadFile.transferTo(new File(F:\\node\\idea\\test\\ originalFilename));}//多文件上传 方式一ResponseBodyRequestMapping(/quick2)public void save2(RequestParam(username) String username, RequestParam(uploadFile1) MultipartFile uploadFile1, RequestParam(uploadFile2) MultipartFile uploadFile2) throws IOException {System.out.println(username);System.out.println(uploadFile1);System.out.println(uploadFile2);// 获取上传文件1的文件名String originalFilename1 uploadFile1.getOriginalFilename();// 保存文件1uploadFile1.transferTo(new File(F:\\node\\idea\\test\\ originalFilename1));// 获取上传文件2的文件名String originalFilename2 uploadFile2.getOriginalFilename();// 保存文件2uploadFile2.transferTo(new File(F:\\node\\idea\\test\\ originalFilename2));}// 多文件上传 方式二ResponseBodyRequestMapping(/quick3)public void save3(RequestParam(username) String username, RequestParam(uploadFiles) MultipartFile[] uploadFiles) throws IOException {System.out.println(username);for (MultipartFile file : uploadFiles) {System.out.println(file);// 获取上传文件名String originalFilename file.getOriginalFilename();// 保存文件file.transferTo(new File(F:\\node\\idea\\test\\ originalFilename));}} }获取Rest风格的请求参数 Restful定义 根据REST风格对资源进行访问称为Restful Rest风格 Rest是一种软件架构风格、设计风格而不是标准 它只是提供了一组设计原则和约束条件主要用于客户端和服务器交互类的软件 基于该风格的软件会更简洁更有层次更易实现缓存机制等 可以利用Rest风格来省略请求参数名的书写即简化书写比如 http://localhost:8080/SpringMvcThree/user/quick6?namezhangsan可改写为 http://localhost:8080/SpringMvcThree/user/quick6/zhangsan隐藏资源的访问行为无法通过地址得知对资源进行的是什么操作比如 http://localhost/user/saveUser http://localhost/user/deleteUser http://localhost/user/updateUser均可改写为 http://localhost/user此时会根据请求方式来判断执行的是哪个方法 当使用Rest风格来获取请求参数时需要在方法的RequestMapping注解中用占位符指明映射地址后的为请求参数同时用PathVariable注解来修饰业务方法中的参数且该注解的value值要与RequestMapping注解中的占位符名称一致 Rest风格请求使用的是url请求方式来表示一次请求目的Http协议中有4种操作方式 GET:用于获取资源 /users/1 GET:获取id1的user POST:用于新增/保存资源 /users POST:新增/保存user PUT:用于修改/更新资源 /users/1 PUT:修改/更新id1的user DELETE:用于删除资源 /users/1 DELETE:删除id1的user 注意 描述模块的名称通常使用复数也就是加s的格式描述表示此类资源而非单个资源例如users、books、accounts…… 用到的主要注解 RequestMapping(value, method) method用来指定操作方式PathVatiableGetMapping(value)设置当前控制器方法Get请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Get)PostMapping(value)设置当前控制器方法Post请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Post)PutMapping(value)设置当前控制器方法Put请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Put)DeleteMapping(value)设置当前控制器方法Delete请求访问路径以及Restful风格的动作等同于RequestMapping(value, methodRequestMethod.Delete)以上注解可详见SpringMVC注解解析部分内容 简单代码示例 在controller包下创建UserControllerTwo类并在该类中添加save1方法完整代码如下 package at.guigu.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;Controller RequestMapping(/user2) public class UserControllerTwo {// Restful风格的请求参数ResponseBodyRequestMapping(/quickk1/{name})public void save1(PathVariable(value name) String userName) {System.out.println(userName);} }SpringMVC拦截器interceptor 定义 SpringMVC拦截器interceptor是一种动态拦截方法调用的机制在SpringMVC中动态拦截控制器方法的执行SpringMVC拦截器interceptor类似于Servlet开发中所使用的过滤器Filter用于对处理器进行预处理和后处理拦截器是AOP思想的具体体现 作用 在指定方法调用的前后执行预先设定的代码阻止原始方法的执行 在实际应用中会将拦截器interceptor按一定顺序联结成一条链该链被称为拦截器链Interceptor Chain 在访问被拦截的方法或字段时拦截器链中的拦截器就会按其之前定义的顺序被调用 拦截器Interceptor和过滤器Filter的区别 区别过滤器拦截器适用范围是servlet规范中的一部分任何JavaWeb工程都可以使用是SpringMVC框架自己的只有使用了SpringMVC框架的工程才能使用拦截范围在url-pattern中配置了/*后会对所有要访问的资源进行拦截增强在mvc:mapping path/中配置了/**之后也会对所有资源进行拦截增强但是可以通过mvc:exclude-mapping path/标签排除不需要拦截的资源 步骤 创建实现HandlerInterceptor接口的实现类并重写它的三个方法在SpringMVC的核心配置文件中配置拦截器测试拦截器的拦截效果 快速入门 配置文件形式 注意此处仅弄一个简单环境来测试拦截器所以准备工作均省略可详见快速入门以及SpringMVC数据响应部分内容完整框架如图所示 以上形式还未配置拦截器所以运行后前面能接收到响应如图所示现要求进行拦截器配置 Step1 创建一个与三层架构包同级的interceptor包并在该包下创建一个实现HandlerInterceptor接口的拦截器类代码如下 package at.guigu.interceptor;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {// 在原始方法即目标方法执行之前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running...);return false;}// 在原始方法即目标方法执行之后视图对象返回之前执行Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle Running...);}// 在整个请求完成之后执行即在原始方法执行完并且视图对象也已返回之后执行Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running...);} }Step2 在SpringMVC的核心配置文件中配置拦截器 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://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/!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的视图名称前缀属性prefix的值设为/jsp/--property nameprefix value/jsp//property!--将InternalResourceViewResolver类中的视图名称后缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--配置静态资源的路径映射让 Spring MVC 可以处理静态文件--mvc:default-servlet-handler/!--配置拦截器--mvc:interceptorsmvc:interceptor!--定义拦截器的作用范围此处表示拦截所有请求路径--mvc:mapping path/**/!--定义拦截器的具体实现类class属性值为对应实现类的全限定名--bean classat.guigu.interceptor.MyInterceptor//mvc:interceptor/mvc:interceptors /beans配置文件形式运行后截图如下 Step3 测试拦截器拦截效果 在以上运行截图中只执行了preHandle方法是因为当它的返回值为true表示请求可以交给Controller来执行原始方法反之则请求被拦截此时只会执行preHandle方法 此时若将其返回值改true代码如下 package at.guigu.interceptor;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {// 在原始方法即目标方法执行之前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running...);return true;}// 在原始方法即目标方法执行之后视图对象返回之前执行Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle Running...);}// 在整个请求完成之后执行即在原始方法执行完并且视图对象也以返回之后执行Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running...);} }此时的运行截图如下 配置类形式方法一 注意此处仅弄一个简单环境来测试拦截器所以准备工作均省略可详见快速入门以及SpringMVC数据响应部分内容完整框架如图所示 以上形式还未配置拦截器所以运行后前面能接收到响应如图所示现要求进行拦截器配置 Step1 创建一个与三层架构包同级的interceptor包并在该包下创建一个实现HandlerInterceptor接口的拦截器类代码如下 注意要给该类加上Component注解作用实例化bean package at.guigu.interceptor;import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;Component public class MyInterceptor implements HandlerInterceptor {// 在原始方法即目标方法执行之前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running...);return false;}// 在原始方法即目标方法执行之后视图对象返回之前执行Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle Running...);}// 在整个请求完成之后执行即在原始方法执行完并且视图对象也以返回之后执行Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running...);} }Step2 在config包下创建配置静态资源以及拦截器的路径映射类即继承WebMvcConfigurationSupport类的子类SpringMvcSupport代码如下 依赖注入MyInterceptor的bean重写addInterceptors方法 package at.guigu.config;import at.guigu.interceptor.MyInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;// 配置静态资源以及拦截器的路径映射 Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport {Autowiredprivate MyInterceptor myInterceptor;Overrideprotected void addResourceHandlers (ResourceHandlerRegistry registry) {// 配置静态资源路径映射registry.addResourceHandler(/xxx/**).addResourceLocations(/xxx/);}Overrideprotected void addInterceptors(InterceptorRegistry registry) {//addInterceptor定义拦截器的具体实现类//addPathPatterns的参数代表拦截所有请求路径registry.addInterceptor(myInterceptor).addPathPatterns(/**);} }Step3 在SpringMVC的核心配置类中利用ComponentScan注解扫描拦截器类MyInterceptor以及SpringMvcSupport类所在包 package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan({at.guigu.controller, at.guigu.interceptor, at.guigu.config}) // 自动配置 Spring MVC 的各种特性 EnableWebMvc public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/jsp/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;} }配置类形式运行后截图如下 Step4 测试拦截器拦截效果 在以上运行截图中只执行了preHandle方法是因为当它的返回值为true表示请求可以交给Controller来执行原始方法反之则请求被拦截此时只会执行preHandle方法 此时若将其返回值改true代码如下 package at.guigu.interceptor;import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;Component public class MyInterceptor implements HandlerInterceptor {// 在原始方法即目标方法执行之前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running...);return true;}// 在原始方法即目标方法执行之后视图对象返回之前执行Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle Running...);}// 在整个请求完成之后执行即在原始方法执行完并且视图对象也以返回之后执行Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running...);} }此时的运行截图如下 配置类形式方法二 此处配置类形式方法一中可以将第二、三步合并即让SpringMVC的核心配置类SpringMvcConfiguration继承WebMvcConfigurer接口并重写其中的addInterceptors方法来进行拦截器的路径映射配置步骤如下 Step1 创建一个与三层架构包同级的interceptor包并在该包下创建一个实现HandlerInterceptor接口的拦截器类代码略 Step2 让SpringMVC的核心配置类SpringMvcConfiguration继承WebMvcConfigurer接口并重写其中的addInterceptors方法来进行拦截器的路径映射配置代码如下 package at.guigu.config;import at.guigu.interceptor.MyInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan(at.guigu.controller) // 自动配置 Spring MVC 的各种特性 EnableWebMvc public class SpringMvcConfiguration implements WebMvcConfigurer {// 依赖注入拦截器的beanAutowiredprivate MyInterceptor myInterceptor;// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/jsp/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;}// 配置静态资源路径Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 配置静态资源路径映射registry.addResourceHandler(/xxx/**).addResourceLocations(/xxx/);}// 配置拦截器路径Overridepublic void addInterceptors(InterceptorRegistry registry) {//addInterceptor定义拦截器的具体实现类//addPathPatterns的参数代表拦截所有请求路径registry.addInterceptor(myInterceptor).addPathPatterns(/**);} }运行截图略 HandlerInterceptor接口详解 HandlerInterceptor接口方法 HandlerInterceptor接口方法解释default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception在请求到达Controller之前执行即在在原始方法即目标方法执行之前执行用于执行预处理逻辑。default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable ModelAndView modelAndView) throws Exception在Controller处理完请求之后视图渲染之前执行即在原始方法目标方法执行之后视图对象返回之前执行default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable Exception ex) throws Exception在整个请求完成之后执行即在原始方法执行完并且视图对象也已返回之后执行。注意即使在Controller或视图渲染过程中抛出异常该方法也会执行 方法对应参数及返回值详解相同参数不在重复解释 preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)——前置处理方法 HttpServletRequest :请求对象HttpServletResponse :响应对象handler :被调用的处理器对象本质上是一个方法对象对反射技术中的Method对象进行了再包装return true 表示请求可以交给Controller来执行原始方法。当为拦截链环境时会将请求交给下一个Interceptor的前置处理方法直到所有前置处理方法均通过后会交给Controller来执行原始方法return false 表示请求被拦截Controller控制器和拦截链上后续的Interceptor都不会继续执行 postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable ModelAndView modelAndView)——后置处理方法 ModelAndView 如果处理器执行完成具有返回结果可以读取到对应数据与页面信息并进行跳转调用该方法的前提是前置处理方法的返回值为true afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable Exception ex)——完成后处理方法 Exception : 如果处理器执行过程中出现异常对象可以针对异常情况进行单独处理调用该方法的前提是前置处理方法的返回值为true无论处理器方法内部是否出现异常该方法均会执行 preHandle方法经常用于执行预处理逻辑比如 验证用户身份或权限。 检查请求参数是否合法。 记录日志或统计请求次数。 当返回值为false时请求被拦截后续逻辑如Controller处理或postHandle、afterCompletion方法不会执行可详见快速入门。此时可以直接设置响应例如返回一个错误状态码或转发或重定向到其他页面。示例如下 在web项目核心目录即webapp下的jsp文件夹中创建error.jsp页面代码如下用于拦截示例 % page contentTypetext/html;charsetUTF-8 languagejava % htmlheadtitleTitle/title/headbodyh1Error.../h1/body /htmlMyInterceptor类的代码更改如下 package at.guigu.interceptor;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {// 在原始方法即目标方法执行之前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running...);String str request.getParameter(param);if (yes.equals(str)) {return true;} else {request.getRequestDispatcher(/jsp/error.jsp).forward(request, response);return false;}}// 在原始方法即目标方法执行之后视图对象返回之前执行Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle Running...);}// 在整个请求完成之后执行即在原始方法执行完并且视图对象也以返回之后执行Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running...);} }当param请求参数值不是yes 当param请求参数值是yes postHandle方法用于对ModelAndView进行修改例如 添加全局数据到视图中如页面标题、用户信息。 根据Controller的处理结果动态调整视图数据。 注意如果Controller方法没有返回ModelAndView如使用ResponseBody或RestController则此方法可能不会被调用。 MyInterceptor类的代码更改如下 package at.guigu.interceptor;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {// 在原始方法即目标方法执行之前执行Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running...);String str request.getParameter(param);if (yes.equals(str)) {return true;} else {request.getRequestDispatcher(/jsp/error.jsp).forward(request, response);return false;}}// 在原始方法即目标方法执行之后视图对象返回之前执行Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {modelAndView.addObject(username, 李四);System.out.println(postHandle Running...);}// 在整个请求完成之后执行即在原始方法执行完并且视图对象也以返回之后执行Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running...);} }拦截器配置详解 在快速入门中配置的是单个拦截器在SpringMVC的核心配置文件中对应的代码如下 !--配置拦截器-- mvc:interceptorsmvc:interceptor!--定义拦截器的作用范围此处表示拦截所有请求路径--mvc:mapping path/**/!--定义拦截器的具体实现类class属性值为对应实现类的全限定名--bean classat.guigu.interceptor.MyInterceptor//mvc:interceptor /mvc:interceptors用到的标签 标签解释mvc:interceptors配置拦截器mvc:interceptors内嵌标签解释mvc:interceptor配置单个拦截器mvc:interceptor内嵌标签解释mvc:mapping path/定义拦截器的作用范围。当path属性为/**时代表拦截所有请求路径当为/xxx/**时代表拦截xxx下的所有资源bean class/定义拦截器的具体实现类class属性值为对应实现类的全限定名 拦截器链 特点 拦截器链执行顺序以拦截器添加顺序为准当拦截器中出现对原始处理器的拦截时后续的拦截器均终止运行当拦截器运行中段时此时仅运行配置在前面的拦截器的afterCompletion即完成后处理方法操作 配置多个拦截器拦截器链步骤配置文件形式 环境准备等工作可见快速入门此处以配置两个拦截器为例 Step1 在interceptor包下创建第二个实现HandlerInterceptor接口的拦截器类并重写其中的方法代码如下 package at.guigu.interceptor;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyInterceptorTwo implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running222...);return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle Running222...);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running222...);} }Step2 在SpringMVC的核心配置文件中配置拦截器 !--配置拦截器-- mvc:interceptors!--配置第一个拦截器实现类--mvc:interceptor!--定义拦截器的作用范围此处表示拦截所有请求路径--mvc:mapping path/**/!--定义拦截器的具体实现类class属性值为对应实现类的全限定名--bean classat.guigu.interceptor.MyInterceptor//mvc:interceptor!--配置第二个拦截器实现类--mvc:interceptor!--定义拦截器的作用范围此处表示拦截所有请求路径--mvc:mapping path/**/!--定义拦截器的具体实现类class属性值为对应实现类的全限定名--bean classat.guigu.interceptor.MyInterceptorTwo//mvc:interceptor /mvc:interceptorsSpringMVC核心配置文件完整代码如下 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://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/!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的视图名称前缀属性prefix的值设为/jsp/--property nameprefix value/jsp//property!--将InternalResourceViewResolver类中的视图名称后缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--配置静态资源的路径映射让 Spring MVC 可以处理静态文件--mvc:default-servlet-handler/!--配置拦截器--mvc:interceptors!--配置第一个拦截器实现类--mvc:interceptor!--定义拦截器的作用范围此处表示拦截所有请求路径--mvc:mapping path/**/!--定义拦截器的具体实现类class属性值为对应实现类的全限定名--bean classat.guigu.interceptor.MyInterceptor//mvc:interceptor!--配置第二个拦截器实现类--mvc:interceptor!--定义拦截器的作用范围此处表示拦截所有请求路径--mvc:mapping path/**/!--定义拦截器的具体实现类class属性值为对应实现类的全限定名--bean classat.guigu.interceptor.MyInterceptorTwo//mvc:interceptor/mvc:interceptors /beans配置多个拦截器拦截器链步骤配置类形式 环境准备等工作可见快速入门此处以配置两个拦截器为例 Step1 在interceptor包下创建第二个实现HandlerInterceptor接口的拦截器类并重写其中的方法代码如下 package at.guigu.interceptor;import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; Component public class MyInterceptorTwo implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle Running222...);return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle Running222...);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion Running222...);} }Step2 在config包下的继承WebMvcConfigurationSupport类的子类SpringMvcSupport中依赖注入MyInterceptorTwo的bean代码如下 package at.guigu.config;import at.guigu.interceptor.MyInterceptor; import at.guigu.interceptor.MyInterceptorTwo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;// 配置静态资源以及拦截器的路径映射 Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport {Autowiredprivate MyInterceptor myInterceptor;Autowiredprivate MyInterceptorTwo myInterceptorTwo;// 配置静态资源路径Overrideprotected void addResourceHandlers (ResourceHandlerRegistry registry) {// 配置静态资源路径映射registry.addResourceHandler(/xxx/**).addResourceLocations(/xxx/);}// 配置拦截器路径Overrideprotected void addInterceptors(InterceptorRegistry registry) {//addInterceptor定义拦截器的具体实现类//addPathPatterns的参数代表拦截所有请求路径registry.addInterceptor(myInterceptor).addPathPatterns(/**);registry.addInterceptor(myInterceptorTwo).addPathPatterns(/**);} }Step3 在SpringMVC的核心配置类中利用ComponentScan注解扫描拦截器类MyInterceptor以及SpringMvcSupport类所在包代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan({at.guigu.controller, at.guigu.interceptor, at.guigu.config}) // 自动配置 Spring MVC 的各种特性 EnableWebMvc public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/jsp/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;} }SpringMVC异常处理 异常常见位置与诱因 框架内部抛出的异常因使用不合规导致数据层抛出的异常因外部服务器故障导致例如服务器访问超时业务层抛出的异常因业务逻辑书写错误导致例如遍历业务书写操作导致索引异常等表现层抛出的异常因数据收集、校验等规则导致例如不匹配的数据类型间导致异常工具类抛出的异常因工具类书写不严谨不够健壮导致例如必要释放的连接长期未释放等 项目异常分类及处理方案 项目异常分类场景处理步骤业务异常BusinessException1.规范的用户行为产生的异常2.不规范的用户行为操作产生的异常发送对应消息传递给用户提醒规范操作系统异常SystemException项目运行过程中可预计且无法避免的异常1.记录日志2.发送固定消息传递给用户安抚用户3.发送特定消息给运维人员提醒维护其他异常Exception编程人员未预期到的异常1.发送固定消息传递给用户安抚用户2.发送特定消息给编程人员提醒维护纳入预期范围内3.记录日志 系统异常分类 系统异常SystemException分类解决方式预期异常通过捕获异常获取异常信息运行时异常RuntimeException通过规范代码开发、测试等手段减少运行时异常发生 异常处理思路 在ssm框架中各个层级出现的所有均异常向上抛出到表现层进行处理持久层抛给业务层业务层抛给表现层表现层继续向上抛出给SpringMVC的核心前端控制器最后由SpringMVC的核心前端控制器交由异常处理器进行异常处理 异常处理器 底层使用的是AOP的思想它能够集中统一的处理项目中出现的异常 异常处理的方式 简单异常处理使用SpringMVC提供的简单异常处理器SimpleMappingExceptionResolver自定义异常处理 方式一实现SpringMVC的异常处理接口HandlerExceptionResolver来自定义自己的异常处理器方式二 自定义异常的方式 自定义异常方式使用场景创建继承RuntimeException运行时异常的子类程序内部的错误或不可恢复的错误不强制要求捕获或声明创建继承Exception可检查异常的子类用于可恢复的错误或外部因素引起的错误需要强制要求捕获或声明 注意 ​ 1.在本示例中并没有分太清只是为了演示作用后续真实项目可根据情况选择 ​ 2.在配置文件形式的示例中创建继承Exception可检查异常的子类来创建自定义的异常 ​ 3.在配置类形式的示例中创建继承RuntimeException运行时异常的子类来创建自定义的异常。 ​ 4.通过创建继承Exception可检查异常的子类来创建自定义的异常在示例中只进行了简写并未完整给出具体操作代码而在创建继承RuntimeException运行时异常的子类来创建自定义的异常中进行了详细的书写两者是一样的示例中仅以一个为例进行精写 异常处理的两种方式配置文件形式 环境准备 Step1 导入坐标略可详见快速入门 Step2 右键源代码配置文件目录即资源文件resources→New→XML Configuration File→Spring Config创建Spring和SpringMVC的核心配置文件代码截图如下 Step3 创建业务层service包、controller包、异常exception包代码截图如下 注意在service包中模拟各种异常来进行后续的示例操作 Step4 配置web项目核心目录即webapp下的WEB-INF中的web.xml并在webapp目录下创建jsp文件夹并写入4个页面success.jsp、error.jsp、errorshow1.jsp、errorshow5.jsp代码截图如下 注意success.jsp为无异常时前端显示页面error.jsp为默认错误视图errorshow1.jsp、errorshow5.jsp分别为业务层show1()、show2()方法抛出异常后所映射的视图 此时运行后前端页面会报对应异常分别如下图所示 初始项目结构如下 简单异常的处理配置文件形式 注意SpringMVC已经定义好了该类型的转换器在使用时可根据项目情况在SpringMVC的核心配置文件中进行相应 异常与视图 的映射配置 简单异常处理只需要在SpringMVC核心配置文件中配置异常处理机制即可代码如下 !--配置异常处理机制-- bean classorg.springframework.web.servlet.handler.SimpleMappingExceptionResolverproperty namedefaultErrorView valueerror1/property nameexceptionMappingsmapentry keyat.guigu.exception.MyException valueerror2/entry keyjava.lang.ClassCastException valueerror3//map/property /bean原理 通过SpringMVC提供的简单异常处理器SimpleMappingExceptionResolver配置异常处理机制。当某个异常抛出时Spring会根据配置的 exceptionMappings 映射到异常所对应的视图。如果抛出的异常没有在 exceptionMappings 中配置那么会使用 defaultErrorView 指定的默认错误视图。 示例代码解释 当抛出的异常为MyException时则会映射到视图error2.jsp当抛出异常为ClassCastException时则会映射到视图error3.jsp若抛出的异常没有在 exceptionMappings 中配置则此时按照defaultErrorView即默认异常视图映射到error1.jsp 注意 在配置异常处理机制的代码中视图均为带后缀名.jsp是因为已在SpringMVC的核心配置文件中提前配置了内部资源视图解析器 代码运行示例 未在SpringMVC核心配置文件中配置异常处理机制时此时由于有异常所以前端会显示异常页面可详见环境准备中的运行截图 在SpringMVC核心配置文件中配置异常处理机制完整代码如下 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://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/!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的视图名称前缀属性prefix的值设为/jsp/--property nameprefix value/jsp//property!--将InternalResourceViewResolver类中的视图名称后缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--配置静态资源的路径映射让 Spring MVC 可以处理静态文件--mvc:default-servlet-handler/!--配置异常处理机制--bean classorg.springframework.web.servlet.handler.SimpleMappingExceptionResolverproperty namedefaultErrorView valueerror/property nameexceptionMappingsmapentry keyjava.lang.ClassCastException valueerrorShow1/entry keyat.guigu.exception.MyException valueerrorshow5//map/property/bean /beans运行截图如下 show1() ClassCastException异常自动映射到errorShow1.jsp页面 show5() 自定义MyException异常自动映射到errorShow5.jsp页面 其它异常自动映射到error.jsp页面 自定义异常的处理方式一配置文件及配置类形式 步骤 在exception包下创建继承Exception可检查异常的子类来创建自定义的异常创建实现HandlerExceptionResolver接口的异常处理器类在SpingMVC的核心配置文件或配置类中配置自定义异常处理机制编写异常映射页面测试异常跳转 代码实现 Step1 创建继承Exception可检查异常的子类来创建自定义的异常 本步骤已在环境准备中完成此处省略 Step2 创建一个与三层架构包同级的resolver包并在该包下创建一个实现HandlerExceptionResolver接口的异常处理器类MyExceptionResolver并重写其中的resolveException方法代码如下 package at.guigu.resolver;import at.guigu.exception.MyException; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class MyExceptionResolver implements HandlerExceptionResolver {/**** param httpServletRequest* param httpServletResponse* param o* param e:为抛出的异常对象* return :返回ModelAndView对象为异常映射的视图*/Overridepublic ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {ModelAndView modelAndView new ModelAndView();// 若是ClassCastException异常则映射到errorShow1.jsp页面if (e instanceof ClassCastException) {modelAndView.setViewName(errorShow1);// 若是自定义MyException异常则映射到errorShow5.jsp页面} else if (e instanceof MyException) {modelAndView.setViewName(errorShow5);// 若是其它异常则映射到error.jsp页面} else {modelAndView.setViewName(error);}return modelAndView;} }Step3 在SpingMVC的核心配置文件或配置类中配置自定义异常处理机制代码如下 SpingMVC的核心配置文件 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://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/!--配置Controller层的注解的组件扫描--context:component-scan base-packageat.guigu.controller/context:component-scan!--等同于context:component-scan base-packageat.guigutype指定要扫描的内容为注解expression指定要扫描的对应注解的全限定名只扫描at.guigu包下有Controller注解的类context:include-filter typeannotation expressionorg.springframework.stereotype.Controller//context:component-scan--!--配置内部资源视图解析器--bean idviewResolver classorg.springframework.web.servlet.view.InternalResourceViewResolver!--将InternalResourceViewResolver类中的视图名称前缀属性prefix的值设为/jsp/--property nameprefix value/jsp//property!--将InternalResourceViewResolver类中的视图名称后缀属性suffix的值设为.jsp--property namesuffix value.jsp/property/bean!--配置静态资源的路径映射让 Spring MVC 可以处理静态文件--mvc:default-servlet-handler/!--配置异常处理机制bean classorg.springframework.web.servlet.handler.SimpleMappingExceptionResolverproperty namedefaultErrorView valueerror/property nameexceptionMappingsmapentry keyjava.lang.ClassCastException valueerrorShow1/entry keyat.guigu.exception.MyException valueerrorShow5//map/property/bean--!--配置自定义异常处理机制--bean classat.guigu.resolver.MyExceptionResolver/ /beansSpingMVC的核心配置类 package at.guigu.config;import at.guigu.resolver.MyExceptionResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller/context:component-scan // 加载controller对应的bean ComponentScan(basePackages {at.guigu.controller}) // 自动配置 Spring MVC 的各种特性,比如类型转换器、mvc的注解驱动mvc:annotation-driven/ EnableWebMvc // 引入配置静态资源类 Import(SpringMvcSupport.class) public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/jsp/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;}// 配置自定义异常处理器Beanpublic MyExceptionResolver myExceptionResolver() {return new MyExceptionResolver();} }Step4 编写异常映射页面。本步骤已在环境准备工作中实现此处省略 运行截图如下 show1() ClassCastException异常自动映射到errorShow1.jsp页面 show5() 自定义MyException异常自动映射到errorShow5.jsp页面 其它异常自动映射到error.jsp页面 异常处理的两种方式配置类形式 方式一简单异常处理使用SpringMVC提供的简单异常处理器SimpleMappingExceptionResolver 方式二自定义异常的处理实现Spring的异常处理接口HandlerExceptionResolver自定义自己的异常处理器 用到的注解如下 类注解解释ControllerAdvice定义全局的异常处理、数据绑定、全局模型属性等功能用于集中处理多个控制器中的异常、数据绑定、模型属性等RestControllerAdvice定义全局的异常处理、数据绑定、全局模型属性等功能用于集中处理多个控制器中的异常、数据绑定、模型属性等方法注解解释ExceptionHandler设置指定异常的处理方案出现异常后终止原始控制器执行并转入当前方法执行 环境准备 Step1 导入坐标略可详见快速入门 Step2 创建config包并在该包下创建Spring核心配置类SpringConfigurationSpringMVC核心配置类SpringMvcConfiguration、配置静态资源的继承WebMvcConfigurationSupport类的子类SpringMvcSupport、代替web.xml文件的继承AbstractAnnotationConfigDispatcherServletInitializer的子类ServletConfiguration如图所示 Step3 创建业务层service包、controller包、异常exception包代码截图如下 注意在service包中模拟各种异常来进行后续的示例操作 Step4 在webapp目录下创建jsp文件夹并写入4个页面success.jsp、error.jsp、errorshow1.jsp、errorshow5.jsp代码截图如下 注意success.jsp为无异常时前端显示页面error.jsp为默认错误视图errorshow1.jsp、errorshow5.jsp分别为业务层show1()、show2()方法抛出异常后所映射的视图 此时运行后前端页面会报对应异常分别如下图所示 简单异常的处理配置类形式 Step1 在controller包下创建ProjectEcepAdvice类代码如下 Step1-1 添加ControllerAdvice注解或RestControllerAdvice注解 若当前controller包下使用的是Controller注解则为ProjectEcepAdvice类添加ControllerAdvice注解若当前controller包下使用的是RestController注解则为ProjectEcepAdvice类添加RestControllerAdvice注解 Step1-2 写一个处理异常的方法doException并将拦截的异常作为参数传入Step1-3 给该方法添加一个ExceptionHandler(value)注解并设置value属性以此来指定捕获的异常类型 捕获所有类型异常ExceptionHandler(Exception.class)捕获指定类型异常ExceptionHandler({FileNotFoundException.class, IOException.class}) package at.guigu.controller;import at.guigu.exception.MyException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView;ControllerAdvice public class ProjectEcepAdvice {// 捕获所有异常进行处理ExceptionHandler(Exception.class)public ModelAndView doException(Exception e){ModelAndView modelAndView new ModelAndView();// 若是ClassCastException异常则映射到errorShow1.jsp页面if (e instanceof ClassCastException) {modelAndView.setViewName(errorShow1);// 若是自定义MyException异常则映射到errorShow5.jsp页面} else if (e instanceof MyException) {modelAndView.setViewName(errorShow5);// 若是其它异常则映射到error.jsp页面} else {modelAndView.setViewName(error);}return modelAndView;} }运行截图如下 show1() ClassCastException异常自动映射到errorShow1.jsp页面 show5() 自定义MyException异常自动映射到errorShow5.jsp页面 其它异常自动映射到error.jsp页面 注意若ProjectEcepAdvice类并未在controller包下而是在其它包下则此时需要在SpringMVC的核心配置类中用ComponentScan注解引入比如 此时我并未在controller包下创建该类而是创建了一个与三层架构包同级的advice包并在该包下创建ProjectEcepAdvice类此时就需要SpringMVC的核心配置类中利用ComponentScan注解引入该包让其能够扫描到代码如下 package at.guigu.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;// 该注解代表该类是SpringMVC的核心配置类 Configuration // 配置注解的组件扫描context:component-scan base-packageat.guigu.controller, at.guigu.advice/context:component-scan // 加载controller对应的bean ComponentScan(basePackages {at.guigu.controller, at.guigu.advice}) // 自动配置 Spring MVC 的各种特性,比如类型转换器、mvc的注解驱动mvc:annotation-driven/ //EnableWebMvc // 引入配置静态资源类 Import(SpringMvcSupport.class) public class SpringMvcConfiguration {// 配置视图解析器Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver new InternalResourceViewResolver();resolver.setPrefix(/jsp/); // 设置视图文件路径前缀resolver.setSuffix(.jsp); // 设置视图文件后缀return resolver;} }自定义异常的处理配置类形式 步骤 在exception包下创建继承RuntimeException的子类SystemException来自定义一个异常在SpingMVC的核心配置文件中配置自定义异常处理机制编写异常映射页面测试异常跳转 代码实现 Step1 创建一个与三层架构包同级的exception包并在该包下创建继承RuntimeException的子类SystemException来自定义一个系统异常 代码如下 设置一个code私有属性来接收异常对应的编号添加构造器注意RuntimeException有5个构造器可根据需要选用一个或多个添加get、set方法 package at.guigu.exception;public class SystemException extends RuntimeException {// 给异常添加编号private Integer code;// 添加构造方法public SystemException(Integer code, String message) {super(message);this.code code;}public SystemException(Integer code, String message, Throwable cause) {super(message, cause);this.code code;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;} }Step2 按照第一步在创建一个BusinessException类来自定义一个业务异常 代码如下 package at.guigu.exception;public class BusinessException extends RuntimeException {// 给异常添加编号private Integer code;// 添加构造方法public BusinessException(Integer code, String message) {super(message);this.code code;}public BusinessException(Integer code, String message, Throwable cause) {super(message, cause);this.code code;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;} }Step3 在controller包下创建Code类来封装自定义异常的响应码,代码如下 package at.guigu.controller;public class Code {// 50001代表自定义异常BusinessExceptionpublic static final Integer BUSS_ERR 50001;// 50002代表自定义异常SystemExceptionpublic static final Integer SYST_ERR 50002;// 50003代表自定义MyException异常public static final Integer MYEXECP_ERR 50003;// 50004代表除自定义异常外的其它异常public static final Integer OTHER_ERR 50004; }Step4 将业务层中可能出现的异常进行拦截包装然年将其转换成自定义的异常代码如下 此处只进行部分演示 package at.guigu.service;import at.guigu.controller.Code;import at.guigu.exception.MyException;import at.guigu.exception.BusinessException;import at.guigu.exception.SystemException;import org.springframework.stereotype.Service;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;Servicepublic class UserService {public void show1() {// 将show1()抛出的类型转换异常拦截包装并将其转换成自定义的异常Object str zhangsan;if (str zhangsan) {throw new BusinessException(Code.BUSS_ERR, 抛出类型转换异常);}}public void show2() {// 将show2()抛出的除0异常拦截包装并将其转换成自定义的异常try {int i 1/0;} catch (Exception e) {throw new SystemException(Code.SYST_ERR, 抛出除0异常请重新输入除数, e);}}public void show3() throws FileNotFoundException {System.out.println(抛出文件找不到异常);InputStream inputStream new FileInputStream(C:/xxx/xxx/xxx.txt);}public void show4() {System.out.println(抛出空指针异常);String str null;str.length();}public void show5() throws MyException {System.out.println(抛出自定义异常);throw new MyException();}}Step6 在controller包下创建ProjectEcepAdvice类代码如下 Step6-1 添加ControllerAdvice注解或RestControllerAdvice注解 若当前controller包下使用的是Controller注解则为ProjectEcepAdvice类添加ControllerAdvice注解若当前controller包下使用的是RestController注解则为ProjectEcepAdvice类添加RestControllerAdvice注解 Step6-2 写一个处理异常的方法doException并将拦截的异常作为参数传入Step6-3 给该方法添加一个ExceptionHandler(value)注解并设置value属性以此来指定捕获的异常类型 捕获所有类型异常ExceptionHandler(Exception.class)捕获指定类型异常ExceptionHandler({FileNotFoundException.class, IOException.class}) package at.guigu.controller;import at.guigu.exception.BusinessException; import at.guigu.exception.MyException; import at.guigu.exception.SystemException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView;import java.io.FileNotFoundException;ControllerAdvice public class ProjectEcepAdvice {// 捕获指定的自定义异常BusinessException进行处理ExceptionHandler(BusinessException.class)public ModelAndView doBusinessException(BusinessException e){ModelAndView modelAndView new ModelAndView();modelAndView.setViewName(errorShow1);// 发送对应消息传递给用户提醒规范操作return modelAndView;}// 捕获指定的自定义异常SystemException进行处理ExceptionHandler(SystemException.class)public ModelAndView doSystemException(SystemException e){// 记录日志// 发送消息给运维// 发送对应消息传递给用户// 发送邮件以及异常发送给开发人员ModelAndView modelAndView new ModelAndView();modelAndView.setViewName(error);return modelAndView;}// 捕获除自定义异常MyException进行处理ExceptionHandler(MyException.class)public ModelAndView doMyException(MyException e){ModelAndView modelAndView new ModelAndView();modelAndView.setViewName(errorShow5);return modelAndView;}// 捕获除自定义外的其它异常进行处理ExceptionHandler({FileNotFoundException.class, NullPointerException.class})public ModelAndView doException(Exception e){// 记录日志// 发送消息给运维// 发送对应消息传递给用户// 发送邮件以及异常发送给开发人员ModelAndView modelAndView new ModelAndView();modelAndView.setViewName(error);return modelAndView;} }运行截图略
http://www.dnsts.com.cn/news/77427.html

相关文章:

  • 网站怎做百度代码统计北京诚通新新建设有限公司网站
  • 企业查询学历关键词排名优化易下拉排名
  • 网站制作公司排名前十dw网页制作过程
  • 摄影网站开发意义纬天建筑工程信息资讯网
  • 本地电脑做视频网站 外网连接电商网站建设建议
  • 企业的建站方式网站的构建一般要多久
  • 三里屯做网站的公司西安自助网站建设系统
  • 燕郊 网站开发做demo的网站
  • 网站建设要哪些人网站开发代码归属
  • 网站开发的优势app制作视频教程
  • 住建城乡建设部网站哈尔滨seo优化排名
  • 免费发布信息网站有哪些专做兼职的网站
  • 番禺网站排名优化公司免费网站模板库
  • wordpress editor石家庄seo优化公司
  • 赤峰建设厅官方网站陇西做网站的广告店
  • 成都建好的网站出租大连网站设计 仟亿科技
  • 杭州家具网站建设方案社旗网站设计
  • 手机 网站 开发丹阳网站建设报价
  • 查询备案网站方法网站目录
  • 设计网站价格wordpress搭建两个主题
  • 广告网站搭建软件下载安装免费
  • 橙色网站设计深圳网站建设hi0755
  • 网站做长尾词好还是单个词好深圳网站维护服务的公司
  • 18末年年禁止观看网站设计配色推荐的网站
  • 网站做301好不好设计绘图软件
  • 有偷菜餐厅城市建设的网站网站上如何放入地图
  • 重庆市住建局官方网站手机建设中网站首页
  • 什么网站吸引流量网络科技公司有什么职位
  • 西部数码网站管理助手使用教程网站被墙什么意思
  • 做网站编辑工作好不好常州网站建设优化