DefaultServlet:路径的配置为"/"用来拦截所有非jsp文件的请求,处理静态资源文件的回送。
JspServlet:路径的配置为“ *.jsp 与 *.jspx”,用来拦截所有的jsp文件,处理解析Jsp文件并回送HTML文本。
//请求的URI:/User/goods
@RequestMapping("/User/{id}")
public String test(@PathVariable("id")Integer id){
System.out.println(id);//goods
}
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>foreEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
SpringMVC的前台控制器(DispatcherServlet)的继承关系文字说明:
请求得到相应的步骤流程:
doDispath方法利用反射机制调用方法的简解:
mappedHandler = this.getHandler(processedRequest);
//去路径映射信息找到对应的类对象,得到一个处理器对象
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
//利用该处理器对象得到一个处理器的适配器对象
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//利用处理器的适配器对象去执行目标方法,返回值为ModelAndView,这说明了无论你在方法中返回了
String也好ModelAndView也好,最后都是返回的值都是ModelAndView类型。
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
//该语句负责响应数据给页面,渲染页面。
SpringMVC的九大组件:九大组件支持了SpringMVC的核心功能,且都是接口。
SpringMVC如何锁定具体方法并传入参数的执行详解步骤(最难的一步)
首先要清楚一点,不管方法的返回值的类型为什么,在阅读了源码后,知道最终返回的类型都是ModelAndView类型的对象
返回值为String类型或ModelAndView类型时转发与重定向的详解:
视图渲染流程:(将域中的数据在页面显示,页面就是用来渲染数据的)
render(mv,request,response)
直译就是渲染方法,渲染页面View(视图对象)与ViewResolver(视图解析器)
数据绑定:将前台通过超文本传输协议,传来的文本类型数据,转换为对应的Java数据类型,并对日期之类的数据进行格式化,与数据合法性的验证。
绑定过程中必须处理的步骤
数据转换
将前台发送过来的参数数据,转换为对应的Java类型的数据。SpringMVC默认对一些简单的数据类型都有对应的类型转换器。
若是对于请求参数的值,为一个自定义类型,若要将其按照自己定义的类型转换,可以如下编写配置文件,
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.atguigu.component.MyStringToEmployeeConverter">bean>
set>
property>
bean>
<mvc:annotation-driven conversion-service="conversionService">mvc:annotation-driven>
数据格式化(主要是日期)
数据校验
概述:对于前端发送过来的数据,虽然有则前端验证帮我们检验数据,但前端校验主要是利用js进行校验的有太多的方式可以越过,在SpringMVC中可以使用 Hibernate Validator(第三方校验框架)来进行后台数据的校验,Hibernate Validator对Java中给出的一套后台检验数据规范,JSR303,进行了实现,类似于(JDBC的实现)。
使用步骤
添加pom依赖
<dependency>
<groupId>org.hibernate.validatorgroupId>
<artifactId>hibernate-validatorartifactId>
<version>6.1.7.Finalversion>
dependency>
在JavaBean中需要校验的属性上,添加相对应的校验注解
常用的注解
//注意以下每一个注解都有“message”,用于指定数据校验错误时的错误信息。
@AssertFalse 验证注解的元素值是 false
@AssertTrue 验证注解的元素值是 true
@DecimalMax(value=x) 验证注解的元素值小于等于指定的十进制value 值
@DecimalMin(value=x) 验证注解的元素值大于等于指定的十进制value 值
@Digits(integer=整数位数, fraction=小数位数)验证注解的元素值的整数位数和小数位数上限
@Future 验证注解的元素值(日期类型)比当前时间晚
@Max(value=x) 验证注解的元素值小于等于指定的 value值
@Min(value=x) 验证注解的元素值大于等于指定的 value值
@NotNull 验证注解的元素值不是 null
@Null 验证注解的元素值是 null
@Past 验证注解的元素值(日期类型)比当前时间早
@Pattern(regex=正则表达式) 验证注解的元素值不指定的正则表达式匹配
@Size(min=最小值, max=最大值) 验证注解的元素值的在 min 和 max (包含)指定区间之内,如字符长度、集合大小
@Valid 该注解主要用于字段为一个包含其他对象的集合或map或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象。
@NotEmpty 验证注解的元素值不为 null 且不为空(字符串长度不为 0、集合大小不为 0)
@Range(min=最小值, max=最大值)验证注解的元素值在最小值和最大值之间
@NotBlank 验证注解的元素值不为空(不为 null、去
除首位空格后长度为 0),不同于@NotEmpty, @NotBlank 只应用于字符串且在比较时会去除字符串的空格
@Length(min=下限, max=上限) 验证注解的元素值长度在 min 和 max 区间内
@Email 验证注解的元素值是 Email,也可以通过正则表达式和 flag 指定自定义的 email 格式
配置文件的导包
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.12.3version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.12.3version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.12.3version>
dependency>
三个注解
@Controller
public class MyFisrController {
//测试文件的(了解,MVC的做的烂)下载
@RequestMapping("/download")
public ResponseEntity<byte[]> download(HttpServletRequest request){
ServletContext servletContext = request.getServletContext();
String location="/JQuery/jquery-1.7.2.min.js";
String realPath = servletContext.getRealPath(location);
FileInputStream fileInputStream = null;
byte[] bytes=null;
try {
fileInputStream = new FileInputStream(realPath);
bytes = new byte[fileInputStream.available()];
fileInputStream.read(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileInputStream!=null)
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
HttpHeaders httpHeaders=new HttpHeaders();
httpHeaders.set("Content-Disposition","attachment;filename="+"jquery-1.7.2.min.js");
return new ResponseEntity<byte[]>(bytes,httpHeaders, HttpStatus.OK);
}
}
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.4version>
dependency>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="#{20*1024*1024}"/>
<property name="defaultEncoding" value="UTF-8"/>
bean>
//注意前端提交的表单属性必须设置这个:enctype="multipart/form-data"
//测试文件的上传
@RequestMapping("/upLoad")
public String upLoad(Map map,@RequestParam("userImag") MultipartFile multipartFile,String userName){
System.out.println("文件上传表单的Id名"+multipartFile.getName());
System.out.println("文件全名"+multipartFile.getOriginalFilename());
System.out.println("用户名"+userName);
try {
multipartFile.transferTo(new File("D:\\suoying\\"+multipartFile.getOriginalFilename()));
map.put("msg","文件上传成功");
} catch (Exception e) {
map.put("msg","文件上传失败"+e.getMessage());
}
return "forward:index.jsp";
}
//在配置文件中添加如下xml
<mvc:interceptors>
<bean class="com.guolei.interceptor.MyfristInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/test01"/>
<bean class="com.guolei.interceptor.MySecondInterceptor"/>
mvc:interceptor>
mvc:interceptors>
//注意:拦截器执行的顺序,与在SpringMVC配置文件中配置的顺序一致。
//拦截器一
public class MyfristInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("过滤器1:方法执行前");
//注意:返回true控制器方法会执行,返回false控制器方法会执行
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("过滤器1:方法执行后");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("过滤器1:页面渲染后");
}
}
//拦截器二
public class MySecondInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("过滤器2:方法执行前");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("过滤器2:方法执行后");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("过滤器2:页面渲染后");
}
}
public class MyFisrController {
//测试拦截器
@RequestMapping("/test01")
public String test01(){
System.out.println("方法执行中!");
return "success";
}
}
/*
执行结果:
过滤器1:方法执行前
过滤器2:方法执行前
方法执行中!
过滤器2:方法执行后
过滤器1:方法执行后
你好,页面已得到响应!
过滤器2:页面渲染后
过滤器1:页面渲染后
*/
SpringMVC处理异常的解析器为九大组件之一的:handlerExceptionResolvers,默认解析三种内置的异常解析器的实现类。
ExceptionHandlerExceptionResolver的使用
在控制器方法中,自定义异常处理方法
@Controller
public class MyFisrController {
//测试默认异常解析器ExceptionHandlerExceptionResolver
@RequestMapping("/test01")
public String test01(int num){
System.out.println(10/num);
return "success";
}
//自定义异常处理方法
//value属性指定处理什么异常,在本控制器中,所有的数学的异常都会交给这个方法执行。
//传入参数类型为Exception,则自动会将引起的异常对象传入形参,但注意!!!
//这里不能写map等等隐含模型,若要携带错误信息给页面,直接将返回值设置为ModelAndView
@ExceptionHandler(value = {ArithmeticException.class})
public ModelAndView HanderException(Exception exception){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("errorPage");
modelAndView.addObject("ex",exception.getMessage());
return modelAndView;
}
}
创建全局异常处理类的处理方法
//该注解表明,这是个异常处理类,会将该类对象装配到IOC容器中
@ControllerAdvice
public class MyException {
//这里定义的异常处理方法,会处理本项目中抛出的所有对应异常
@ExceptionHandler(value = {NullPointerException.class,ArithmeticException.class})
public ModelAndView HanderException(Exception exception){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("errorPage");
System.out.println("全局异常处理方法已执行"+exception.toString());
modelAndView.addObject("ex",exception.toString());
return modelAndView;
}
}
注意:优先调用异常处理方法为本类定义的。本类无定义再使用全局异常处理方法。
ResponseStatusExceptionResolver的使用
//在方法中抛出该异常类,会展现一个SpringMVC中指定的异常页,并将注解的信息写入异常页
@ResponseStatus(reason = "用户不存在", value = HttpStatus.NOT_EXTENDED)
public class MyHttpException extends RuntimeException{
}
整合的目的:分工明确
方案:SpringMVC和Spring分容器
默认行为:Spring默认是父容器,SpringMVC默认是子容器;子容器可以引用父容器的组件;父容器不能引用子容器的组件;
web.xml文件配置两个容器
DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>foreEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>
classpath:applicationContext.xml
param-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
Spring配置文件的编写
<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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx ">
<context:component-scan base-package="com.guolei">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
context:component-scan>
beans>
SpringMVC配置文件的书写
<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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx ">
<context:component-scan base-package="com.guolei" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
context:component-scan>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
beans>
<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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx ">
<context:component-scan base-package="com.guolei.controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/JspPages/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
beans>