SpringMVC学习笔记

1.WEB-INFO下的资源安全

在Web-INFO下的资源,不能通过浏览器直接访问,需要内部跳转(也就是需要转发,重定向不行)

2.注册中央调度器--->DispatcherServlet

<servlet>
  <servlet-name>springMVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <!--自定义加载mvc配置文件的位置-->
  <!--若不定义,则默认加载web-info下的[servlet-name]-servlet.xml 文件名-->
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-mvc.xml</param-value>
  </init-param>
  <!--随着web容器tomcat的启动而创建。只要是大于0的数值都是可以的,数字越小代表加载的顺序越早-->
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>springMVC</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

3.什么是请求?

  • 地址栏提交
  • 表单提交
  • 超链接
  • 页面图片
  • 引入js库
  • .......等等

4.DispatcherServlet 配置url-pattern的三种方式

  • /* 最大拦截,不管静态,动态资源,统统全部拦截!动态资源:jsp,php。。。
  • /  会拦截静态资源,页面返回404。静态资源:像图片、css、js等
  • *.do   controller访问路劲写好就可以很方便的过滤了。

5.restful请求

安卓系统就是这个请求。这个就必须要使用/的形式了!!而*.do的形式就不行了!

6.restful请求如何处理静态资源访问的问题

(以下方法选一种即可!!)

  1. 在web.xml中,写上:
    需要返回什么资源就写什么后缀,一种资源就要下一个下面的东西。
    <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
    </servlet-mapping>
  2. 在springmvc.xml中配置mvc标签
    <!-- 当在web.xml 中 DispatcherServlet使用 <url-pattern>/</url-pattern> 映射时,能映射静态资源 -->
    <mvc:default-servlet-handler/>
  3. 在springmvc.xml中配置mvc:resources标签
    该标签是spring3.0.4后引入的,专门处理静态资源的访问问题
    <!-- 静态资源映射 -->
    <mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>

7.相对路径和绝对路径

一、绝对路径:以http协议开头的,绝对路径

二、相对路径分两类
①以/开头 ②不以/开头

①以/开头的又分两类:
前端路径:在html,jsp页面中的html(不是在java代码块中的)
后端路径:在java代码中出现的,xml啊,propertites啊,java代码中啊。

前端路径的参照路径是web服务器的根,不包含项目名,如:http://127.0.0.1:8080
后端路径的参照路径是web应用的根,包含项目名,如:http://127.0.0.1:8080/demo01
注意两个后面都是没有/的!

②不以/开头的参照路径是当前访问路径去掉资源路径。
例如当前访问的是:http://127.0.0.1:8080/demo01/xxxxx/ooo/hello.do
那么相对路径就是http://127.0.0.1:8080/demo01/xxxxx/ooo/

8.重定向的特例!!

重定向写的路劲应该按前端路径来看待!!因为重定向了!!记住就好

9.SpirngMVC的流程分析

  • 处理器映射器--->通过url来找到具体对应的Handler,也就是Controller
  • 处理器映射器找到具体的Controller后,将Controller+Interceptor封装到一起,包装成处理器执行链返回
  • 处理器适配器--->查看该Handler也就是Controller是具体实现的哪一个接口,是Controller,还是HttpRequestHandler接口,来决定使用哪一个适配器进行处理Handler对象。

10.SpringMVC中默认的组件配置

11.视图解析器

  • internalResouceViewResolver
  • beanNameViewResolver
  • xmlResouceViewResolver
  • ResourceBundleViewResolver
后面三种是差不多的,如果是访问内部资源就用jstlView,如果是外部资源就用RedirectView
如果要设置视图解析器的优先级,只需设置下order属性即可!,大于0的整数,数字越小加载顺序越早!!
视图分为逻辑视图和物理视图。

12.POST和GET请求

在处理器中默认两种请求都是可接受的!!
一般设置就设置POST请求,单单设置一个GET没有任何意义!

13.解决中文乱码问题

在web.xml中配置一个Spring的字符过滤器CharacterEncodingFilter
<!-- 设置filter编码开始 -->
<filter>
    <filter-name>Set Character Encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>Set Character Encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 设置filter编码结束 -->

14.springMVC中的注解

  • @Controller 标明该类是处理器,需要在配置文件中添加组件扫描器
  • @RequestMapping 映射路径,标在类上就是命名空间,在方法上就是访问的资源路径
  • @RequestParam 设置参数的一些属性,列入,默认值啊,是否是必须的啊等等
  • @ResponseBody 表明该方法响应体返回!需添加mvc注解驱动

15.注解的参数

若注解中有多个参数,如果这样定义@Annotation("aaa"),那么就是赋值给默认属性value

16.Controller层方法的返回值

  • ModelAndView----》既有视图,又有数据
  • void----》1.通过ServletAPI对象(request、response、、)进行跳转和数据处理。
2.ajax跳转。通过response对象拿到printWiter对象的out方法输出,页面的ajax接收即可!一般不用这种,后期用String直接接受即可!
  • String----》1.返回的是本地视图资源
2.视图名(需要注册BeanNameViewResolver),若要返回视图,则不能加@RsponseBody
  • Object----》返回结果对象,是相应体。需要3步
1.添加@ResponseBody
2.添加mvc注解驱动
3.添加jackson核心包
注意,返回响应体若有乱码问题,需要在@RequestMapping中添加produces属性text/html;charset=utf-8
至于produces的属性要用什么,都在MediaType这个类中有定义!!例如:
@RequestMapping(value="/01",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
然后前端用ajax接接收即可。各种类型都可以。

17.重定向与转发

默认是转发,若要重定向则需写上redirect:资源路径
注意,这里的重定向以/开头的路劲依然是后台路劲,绝对于项目。只有Serlet中用response的重定向以/开头是前台路劲,绝对于服务器。
重定向主要是用Model对象,将数据(只能是基本数据)放在model中然后重定向,url后面会自动拼接参数。

18.异常处理

  • SimpleMappingExceptionResolver在xml中注册即可,无需bean的id,设置下错误页面啊,错误信息对象啊,等一些属性即可!这个是最简单的,框架自带的。这种只能简单的设置错误跳转页面,不能在发生异常时做一些其他的处理!
  • 如果想要在发生异常时再一起处理程序,需要用户自定义一个类,并注册!该类继承HandlerExceptionResolver,并重写其方法。
  • 注解式自定义全局异常处理(重点哦)
@ControllerAdvice
//该注解被@Component注解了,所以可以被扫描注入
public class MyAnnotationExceptionHandlerResolver {
    //参数放需要捕获的异常class对象
    @ExceptionHandler(ArithmeticException.class)
    //需要什么参数就放啥参数,可别放太过分的参数哦
    public ModelAndView HandlerException1(Exception e, HttpServletRequest request, HttpServletResponse response){
        ModelAndView mv = new ModelAndView();
        System.out.println("--------");
        System.out.println("执行自定义代码块、、、");
        System.out.println(e);
        System.out.println(request);
        System.out.println(response);
        System.out.println("--------");
        mv.setViewName("/WEB-INF/jsp/error.jsp");
        mv.addObject("ex",e);
        return mv;
    }

    @ExceptionHandler()
    public void HandlerException2(Exception e){
        System.out.println("--------");
        System.out.println("执行自定义代码块、、、");
        System.out.println(e);
        System.out.println("--------");
    }
}

19.类型转换器

基本类型的转换都能轻松完成,框架已经帮我们实现了。
但是有些类型不能转换需要我们自己定义,比如日期,日期有很多种格式...
自定义类型转换器,需要实现接口Converter接口,然后再mvc注解驱动标签要添加conversion-service属性
<mvc:annotation-driven conversion-service=""/>
总的来说,一般定义一个什么类型转换器。。麻烦,一般就都直接在Controller层处理,而且前端页面也会有一些限制。实际工作代码中几乎不用。

20.数据回显

就是表单提交的时候,把用户提交过来的信息都拿过来,然后如果有表单填错的情况,会把之前填的数据再带回去。
其实就是异常处理那里,添加了request对象,从request对象中拿用户填写的信息,然后前端页面用el表达式显示出来。
(用不到吧?)

21.@ControllerAdvice的使用

官方介绍:
表示带注释的类可以帮助“控制器”。
作为一种专业化@Component,允许通过类路径扫描来自动检测实现类。
它通常用于定义@ExceptionHandler, @InitBinder以及@ModelAttribute 适用于所有@RequestMapping方法的方法。
之一的annotations(),basePackageClasses(), basePackages()或它的别名value() 可以被指定,以限定控制器,以协助的特定子集。当应用多个选择器时,应用“或”逻辑 - 意味着选定的控制器应至少匹配一个选择器。
默认行为(即如果使用没有任何选择器),@ControllerAdvice注释类将协助所有已知的控制器。
请注意,这些检查是在运行时完成的,因此添加许多属性并使用多个策略可能会产生负面影响(复杂性,性能)。

简单说就是可以进行全局性的操作。
@ExceptionHandler, @InitBinder以及@ModelAttribute也可以直接用在单个Controller中,但是那样的话就仅仅只是对单个Controller起作用了。

22.@InitBinder的使用

@InitBinder
public void initBinder(WebDataBinder webDataBinder){
    webDataBinder.registerCustomEditor(Date.class,new MyDateEditor());
}
注意:可以注册多个!!底层是Map形式的。自定义一个资源编辑器,重写set方法即可!
webDataBinder.registerCustomEditor(Date.class,new MyDateEditor());
webDataBinder.registerCustomEditor(Date.class,new MyDateEditor());
webDataBinder.registerCustomEditor(Date.class,new MyDateEditor());
自定义propertyEditor类继承PropertiesEditor该类
public class MyDateEditor extends PropertiesEditor{

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        String patten=null;
        if(Pattern.matches("^\\d{4}/\\d{2}/\\d{2}$",text)){   //2017/10/23
            patten="yyyy/MM/dd";
        }
        if(Pattern.matches("^\\d{4}\\d{2}\\d{2}$",text)){   //20171023
            patten="yyyyMMdd";
        }
        if(Pattern.matches("^\\d{4}-\\d{2}-\\d{2}$",text)){   //2017-10-23
            patten="yyyy-MM-dd";
        }
        DateFormat df=new SimpleDateFormat(patten);
        try {
            setValue(df.parse(text));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
在哪个Controller里面里就对哪个Controller起作用,如果是在@ControllerAdvice里面写就是全局有用

24. 验证器 validator

使用的最多的是Hibernate 的验证器。
首先需要导入jar包:
然后再mvc注解驱动中添加如下:
<mvc:annotation-driven validator=""/>
注册本地验证器,设置验证器提供class,然后再注册Hibernate的验证器即可!
<bean id="myValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="providerClass" value=""/>
</bean>
之后就是在实体类的属性上添加像@NotNull啊,@Min啊,@Max啊,@Size啊,@Pattern啊等验证信息即可。
还需要再Controller层写上这样的东西
@Validator不能添加在String和基本类型的前面。
如果验证失败,BindingResult对象中会有所有的错误信息。

项目中应该是几乎不用的。除非是安全性非常高的项目。

25.mvc注解驱动的用处

<mvc:annotation-driven/>
1.处理响应体,@ResponseBody
2.处理类型转换器,添加conversion-service属性
3.处理验证器,添加validator属性
4.处理文件上传
5.....

26.文件上传

1.前端的form表单,method一定要设置为post,且encType为multipart/form-data
2.添加mvc注解驱动
3.添加common的fileupload包
<!--文件上传的支持-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
4.Controller层的配置
@Controller
@RequestMapping("/test")
public class MyController04 {


    @RequestMapping("/upload")
    public String register(MultipartFile img, HttpServletRequest request, HttpSession session) throws Exception {
        String path=session.getServletContext().getRealPath("/images");
        String Filename = img.getOriginalFilename();
        //path根目录,Filename子目录即文件么
        File file=new File(path,Filename);
        img.transferTo(file);
        request.setAttribute("message","上传成功");

        return "/WEB-INF/jsp/hello.jsp";
    }
}
5.在springmvc.xml中配置
<!--这个id必须是这样,这个id已经在DispatcherServlet中定义了,所以id必须是这个-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--设置默认编码解决的是上传上来文件名中若有乱码的问题-->
    <property name="defaultEncoding" value="utf-8"/>
    <!--总上传大小-->
    <property name="maxUploadSize" value="3145728"/>
    <!--单个文件大小-->
    <property name="maxUploadSizePerFile" value="1048576"/>
    <!--大小的单位是字节Byte   1MB=1024*2015 Byte-->
</bean>
上传多个文件的支持,就是在Controller的方法的参数改成MultipartFile[] img 并添加@RequestParam注解,向框架表明,这个类型的参数要组装成一个数组!其他操作和单个文件上传是一样的。

27.拦截器部分

1.需要自己写个类实现HandlerInterceptor接口,并实现里面的三个方法
/**
 * 自定义类实现HandlerInterceptor接口
 */
public class MyInterceptor implements HandlerInterceptor{

    //前置处理器,方法之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行MyInterceptor的---preHandle()方法");
        //true 和 false 来决定是否拦截
        return true;
    }
    
    //后置处理器,只的是方法走完了,但是还没有把数据给视图处理
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("执行MyInterceptor的---postHandle()方法");
    }

    //完成处理器,指的是全部跑完了,已经把数据都处理,马上要把数据给浏览器之前!!!
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行MyInterceptor的---afterCompletion()方法");
    }
}
2.对自己写的拦截器进行注册,需要使用springmvc的标签。
<!--注册拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="ljqwstc.aop.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
拦截器流程图:

多个拦截器处理流程图:

这种图可能会好理解一些:

afterComletion()方法执行的条件是preHandle()方法的执行并且返回true
如果执行了preHandle()并且返回的是true,及时后面还有很多拦截器或者程序抛了异常,afterComletion()还是会执行
有点类似finally 经常会做资源释放的操作。具体的源码可以看Dispatcher的doDispatch()方法



结语:以上这些就是在我学习SpringMVC中的笔记,可能比较粗略,但我写这篇博客也是为了我日后复习使用,随着工作的深入,我会不断对这边博客进行补充。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值