欢迎来到 IT实训基地-南通科迅教育
咨询电话:0513-81107100
Spring MVC 笔记
2017/2/17
科迅教育
334
南通哪有做Web前端培训的?

1.基础步骤

*jar包包含进来+配置核心前端控制器(web.xml/配置map所有请求使用的是/而不是/*,否则会有404发生)+配置组件自动扫描(springContext.xml)+配置视图解析器(springContext.xml)

*编写请求+编写控制器(@Controller)类+编写请求处理方法(@RequestMapping)

2.RequestMapping

*修饰类

*修饰方法

*无论修饰类还是修饰方法,都是用来map请求路径的。修饰类,表示在请求处理方法对应的请求之前再加一个前限定路径,如果请求方法的类上没有加RequestMapping限定,则不加,在类上加的路径限定,通常用来分模块。

*使用RequestMapping除了可以对请求的URL进行map之外,可以对http请求报文的几乎所有内容进行map,包括请求行(请求方法、请求URL),请求头(各种请求头参数),请求主体(请求参数)的映射

*value:是默认参数,即对应map的url

*method:请求方法

*heads:请求头,使用简单表示来映射,param,!param,param="",param!="",{"","",""},注意heads的值可以是单个的值也可以是一个数组,单个的值是个字符串表达式,数组的话也是字符串数组

*params:请求参数,用法同heads

*使用多个条件之间是与的关系,之所以使用这么多的限定条件,是为了更加精确的映射请求,是为了更加精确的映射

*使用通配符,使用通配符可以将多个不同请求但是同类请求映射到同一个控制器类进行处理,使用了Ant风格的通配符

* ?:匹配文件名中的一个字符 /hello/user_? -> /hello/user_a /hello/user_b

* *:匹配文件名中的任意字符(任意多个任意字符)/hello/user_* -> /hello/user_max/hello/user_zhs

* **:匹配多层路径 /hello/**/user -> /hello/a/b/user /hello/a/user

*使用@PathVariable注解,通过使用该注解可以将映射URL中的占位符{**}绑定到控制器处理方法的入参中

*@RequestMapping("/hello/{id}")

public String hello(@PathVariable("id") Integer id){}

*使用URL占位符及@PathVariable注解能简化REST风格的请求的编写

*进行REST风格请求的编写

*配置过滤器使Spring对浏览器发出的请求进行请求方法的转换以支持PUT和DELETE请求,配置使用的过滤器为:HiddenHttpMethodFilter(拦截所有请求使用的是/*,必须是这个,如果是/会出错的,必须是这个,必须)

*使用PUT和DELETE请求的话,需要使用post请求的方式,并且在表单中增加隐藏字段:type="hidden"name="_method" value="put"/"delete"

*对于Tomcat8.0+不支持这个特性,因为Tomcat8.0之后,转发到JSP的请求方法只能是HEAD、POST、GET,如果确实需要使用REST风格的URL,需要写一个过滤器,用来把所有转发的请求的请求方法强制转换为PUT请求

*获取请求参数:@RequestParam作为处理方法的入参

*public Stringhello(@RequestParam(value="",required=true/false,defalutValue="0")Type var),对于使用required为FALSE的参数,不能使用基本数据类型,如果要使用基本数据类型的话需要设置defaultValue

*required的值默认为TRUE

*获取请求头:@RequestHeader作为方法的入参

*使用方法同@RequestParam注解,一模一样

*获取和使用cookie:@CookieValue

*cookie的条数往往不只有一条,使用@RequestHeader进行映射不太方便,但也是OK的,使用单独的这个注解更方便

*用法同@RequestParam注解,一模一样

*使用POJO对象绑定请求参数值

*表单对象往往对应一个POJO对象,如果使用@RequestParam注解一一进行映射的话,成本太高,可以将请求参数绑定到一个POJO

*SpringMVC会自动按照属性名称和POJO的属性名称进行匹配,自动为该对象的属性添值,支持级联属性

*要进行映射的POJO需要满足标准的JAVABean编写规范

*在进行表单数据绑定的过程中,不要求表单数据项集合是POJO属性集合的子集,也不要求POJO属性集合是表单数据项的集合的子集,只绑定能够成功匹配的数据项,但是,对于能够进行绑定的数据项,必须是能够进行合法格式转换的,如果在格式化的过程中发生了异常,就会有400错误。总之,对于数据绑定和在绑定过程中的格式化,要么不匹配,要么匹配并且能够成功格式化

*使用Servlet原生API作为请求处理方法的入参

*直接使用即可:public String hello(HttpServletRequest request)

*HttpServletRequest

*HttpServletResponse

*InputStream

*OutputStream

*HttpSession

*Locale

*Reader

*Writer

*java.security.Principal

3.处理模型数

*请求发过来,然后交由某一个控制器的请求处理方法进行处理,处理完之后可能会有一堆的数据等待进行展示,即模型数据需要进行处理和展示

*使用ModelAndView作为请求处理方法的返回值

*ModelAndView返回值既包括视图也包括数据

*ModelAndView mav = newModelAndView(String viewName)

*addObject(String attributeName,Object attributeValue)

*addAllObject(Map modelMap)

*setView(View view)

*setViewName(String viewName) //这里的viewName在运行中也需要视图解析器进行解析

*作用域为request的作用域,直接使用requestScope.attributeName进行访问即可

*使用addObject/addAllObject方法设置的属性确确实实放到了请求域中了

*使用一个Map或者Mode或者ModelMap类型的变量作为请求处理方法的入参

*直接向Map中添加数据即可,然后在视图页面使用requestScope的域属性进行获取即可

*除了Map之外的剩下两个和Map的用法一样,只用Map就够了

*使用这种方法传递模型数据也是的的确确的放到了请求域

*使用@SessionAttribute注解将模型数据绑定到session域

*这个注解只能放到类(控制器类)上面

*value:String[]:是一个字符串数组,可以放多个键的名字,以把多个属性放到session域中

*type:Class[]:是一个类型数组,有时候同一个类型的属性有多个,可以不实用键的名字,而使用键的类型,以简化代码

*使用这个注解的前提是必须先把属性放到请求域对象中,譬如使用map入参,map.put("user",newUser()),在@SessionAttribute(value = {"user"}),user属性既在请求域中又在session域中

*使用@ModelAttribute注解避免新创建对象,以使新属性在原有对象上进行赋值

*该注解是放到方法上的,该方法在每个请求处理方法之前被调用

*被@ModelAndAttribute标记的方法的作用域仅仅是当前控制器内部,其他控制器内部的请求处理方法执行前并不触发该方法的执行

*该注解对应所有请求,也就是所有请求处理方法执行之前都会被调用

*被该注解修饰的方法可用的入参有

*@RequestParam,用来获取请求参数,不是某个特定请求的,所有请求都要过这个

*Map(必须项,而且键的值为POJO类型首字母小写后的名称,由此来匹配前名称还原后的类型和@RequestMapping注解修饰的方法的入参类型)

*如果不想在Map中添加键值对的时候,键的值必须是POJO类型的第一个字母小写,可以随便写为**,但是在需要使用旧对象入参的请求处理方法中,POJO类型对象变量之前需要加@ModelAttribute("**")

*如果请求处理方法的入参中使用了@ModelAttribute注解的POJO,在请求处理方法执行之前首先需要找到该注解中Value值对应的实际的对象,它首先会在由@ModelAttribute方法修饰的方法中维护的map中查找,有,则返回如果没有则尝试从session中获取,如果session中有对应的键但是改键没有对应的值,则抛出异常

*如果上述的两个位置中都没有找到要找到的对象,则利用反射直接创建一个新的对象

*既然在session中尝试获取没有获取到会抛出异常,怎么还会走到自己利用反射创建一个对象出来呢?

*解释:对于使用了@ModelAttribute注解的方法,在当前控制器中的每个请求处理方法调用之前都会调用这个方法,如果在请求处理方法之中有POJO入参,就开始为这个入参寻找旧POJO对象(名称要么由@ModelAttribute指定要么使用默认:类型首字母小写)以传进来,如果由@ModelAttribute修饰的方法维护的map中没有找到,会进行下一步,即如果该控制器使用@SessionAttributes注解,则会在session中寻找,如果找到了和键的名称一样的键值对,但是值为空,则抛出异常;如果在session中没有找到对应的值,则会创建一个新的对象出来;如果找到就找到。如果该控制器类没有使用@SessionAttributes注解,则直接创建一个新的对象传入请求处理方法

*使用POJO作为请求处理方法的入参,如果该入参能够成功被传入,无论是旧POJO对象还是新创建的对象,该对象都会放到request对象域中,如果指名了@ModelAttribute(value),则键就是这个Value,如果没有指明,则为类型首字母小写

*解释:无论是否使用@ModelAttribute注解,对于请求处理方法的POJO入参都是要经过上述『解释』过程的确定过程,只是如果使用了@ModelAttribute的话,会从其维护的map中查找,如果使用了@SessionAttribute的话,也会从中查找而已,查找键的名称在上述『解释』中提到,要么指定要么默认。总结来说,如果在请求处理方法中使用POJO入参的话,需要注意POJO旧对象的确定方法

4.视图解析器

*无论结果处理方法的返回值是何种类型,Spring MVC都会将其转化为ModelAndView对象

*InternalResourceViewResolver:主要是搞在同一个web目录下通过转发得到的视图

*这个视图解析器默认使用的是InternalResourceView,即JSP页面

*直接使用URL定位到页面,但是如果页面都在WEB-INF下,是不能直接访问到的,可就是想直接访问的话可以配置

*path是相对于该web目录的请求,由于是在JAVA中,需要加上/表示,例如/index就和在HTML页面中使用超链接href为index的效果是一样的

*注意使用这个配置的话,之前再转发到这个View的操作就全404了,避免这种情况,需要再配置vc:annotation-driven>

*BeanNameViewResolver:使用自定义视图

*定义视图解析器的优先级,使用order属性,值越小,优先级越高,InternalResourceViewResolver的order值为Integer.MAX_VALUE

*视图的转发和重定向,如果返回的字符串中含有forward:viewName或者redirect:viewName,SpringMVC会根据指令作响应的处理,使用这种转发和重定向相当于在超链接中写的请求路径一样,而不是解释成等待被解释的逻辑视图的名字

*谈一下html页面中使用到的相对路径,通常常见的是相对于跟路径,但并不是指html中的相对路径都是相对于webapp的跟路径的,相对的路径是地址栏中去掉当前路径的路径,譬如地址栏中为:a/b/c/hah,这个路径下的页面的相对路径为a/b/c/;再譬如:a/b/c/a.jsp,这个路径下的页面的相对路径为a/b/c/,相对于跟路径仅仅是个例而已

5.使用SpringMVC的form标签

*方便回显

*需要添加标签库到jsp页面中

*方便地添加单选按钮

*使用这个标签库需要使用modelAttribute注解绑定模型数据,如果没有这个,则从请求域中找,如果这两个都没有,则报错,为什么呢?因为SpringMVC的form表单认为你一定是需要回显的,即使你是第一次来,那怎么避免这个错误?

*在请求处理方法中添加一个空的表单对象POJO到请求域中即可,默认默认是从请求域中取出名称为『commond』的域对象,OK,要么在form表单中指名modelAttribute的值要么在map中put的时候使用的键的名称为commond,添加的这bean必须和这些个属性一一对应,有一个对不上的就无法正常显示

*path cssClass cssErrorClass

*path对应HTML的form的表单Name属性,支持级联属性

*可以使用html中普通的form表单标签代替这个,使用这个结合高版本的Tomcat会有问题

6.静态资源处理

*因为SpringMVC拦截了所有的请求,而对于静态资源,并没有相关的映射进行配置,所以会有404

*但是对于静态资源的URI是不用进行映射的,直接给就行了

*对于没有进行映射URI,可以当做是静态资源进行处理,通过配置,通过这配置将加载一个DefaultHttpRequestHandler来对所有的请求进行分析,对于没有进行映射的请求讲交由服务器的默认的Servlet进行处理,即名称为default的Servlet进行处理,如果默认的Servlet的名称不是default,则需要default-servlet-name属性进行指定,使用了这个bean之后,需要配置,不然,requestMapping就都会变得不好使了

7.将超链接转化为POST请求

*使用JS可以做到,但是使用JQuery更方便

*就是点了这个超链接之后,执行一个方法,使这个超链接转化为一个表单action的值,Method为post,然后提交该表单

*注意:Tomcat8+之后,对post转DELETE和put的支持,没了。

8.数据绑定、数据格式转换、数据校验

*在Spring中,内置了表单数据的类型转换,变量名相同的数据会进行类型匹配和转换

*数据绑定和数据格式转换是同时进行的,如果在数据绑定和数据格式转换的过程中,出现了异常,或者没有出现异常,数据绑定和数据格式转化的结果都会放到BingdingResult类中

*自定义数据类型转换器(了解)

*@InitBinder注解

*由该注解修饰的方法能够对webDataBinder进行初始化设置,webDataBinder是用来将表单数据绑定到JAVAbean的属性上去的,在绑定的过程中顺便

*@DateTimeFormat(pattern="yyyy-MM-dd"),该注解的位置是在POJO的Date类型的属性上,用来告诉数据绑定器(内部含有格式转换器)应该将什么格式的字符串转换为Date类型的

*@NumberFormat(pattern="##"),#代表数值,用于将特定格式的字符串转换为数值类型的,可以是整型也可是浮点型的

*在开发过程中,注解是必须的,不然有的东西会失效会报错,带上准没错

*使用BindingResult对数据绑定和格式化的结果进行查看,可能出错也可能没有错误,无论有没有错误,都可以使用这个类进行查看,方式为,用一个BindingResult类型的变量作为请求处理方法的入参,即可在请求处理方法中进行处理

*getErrorCount()

*getFieldErrors()->Set

*FieldError

*getField()

*getDefaultMessage()

*数据校验

*如何校验:加一个注解就OK了,使用JSR303标准对JAVABean的属性进行注解标注进行校验即可

*Spring本身并没有提供JSR303的实现,常用的实现有HibernateValidator框架,但是如果要使用这个框架的话需要将这个框架对应的jar包包含进来,外面三个加上required中的几个,另外如果出错的话需要将三个el包加到tomcat的lib下

*需要在Spring的配置文件中配置,以支持数据校验

*需要在bean的要检验的属性上加注解以进行校验

*需要在请求处理方法的POJO入参前加上@Valid注解,以在数据绑定之后进行数据校验

*验证出错后:用@Valid注解的POJO入参和BindingResult之间不能有其他的入参,利用BindingResult对错误结果进行获取

*错误消息国际化和回显

*编写国际化资源文件:

i18n.properties键:注解名称.入参POJO的名称(要么默认要么指定).属性

值:就是要显示的值

*将国际化资源文件配置到Spring的配置文件中

*ResourceBundleMessageSource,要配置的属性

property:basename,value:i18n

9.使用json,简单到没朋友

10.文件的上传下载

*默认情况下,SpringMVC没有装载任何的multipartResolver(是一个接口,有多重实现)

*使用SpringMVC的文件上传下载,需要配置一个multipartResolver的实现类,常用的是commonsMultipartResolver,基于apache的commons-upload

*将commons-fileupload的jar包考到lib下,需要将commons-io也考过来

*在Spring的配置文件中配置CommonsMultipartResolver,注意需要配置bean的id,否则不会被Spring上下文加载

*配置默认的字符编码:defaultEncoding

*配置上传文件大小限制:maxUploadSize

*在请求处理方法的入参直接添加@RequestParam注解,即可获取到提交的form表单的数据,包括普通字段和file字段,用于接受file类型字段的类型叫MultipartFile-file类型

*getOriginalName:获取文件名称

*getInputStream:获取文件对应的输入流

11.自定义拦截器

*编写拦截器,只需实现HandlerInterceptor接口即其中的方法即可

*booleanpreHandle():在请求处理方法执行之前被调用,如果返回值为FALSE,后续的拦截器不会被调用,而且目标方法不执行,可以考虑作权限、日志、事务等

*postHandle(request,response,mv):在调用请求处理方法之后和渲染视图之前调用的,可以修改请求域和ModelandView的东西,如转向的视图等

*afterCompletion:在渲染视图之后被调用,释放资源

*在Spring的配置文件中配置拦截器,使用

*上述拦截器拦截所有请求

*除了可以直接配置bean之外还可以配置,通过这个子节点可以进行更详尽的配置

*属性: 配置作用和不作用的路径

*属性:

*拦截器的执行顺序

*pre按照在配置文件中位置的顺序执行

*post按照在配置文件中位置的反序执行

*after按照在配置文件中位置的反序执行

*在拦截器链上如果某一个拦截器的pre返回了false,则之后的拦截器不再执行,而且之前的post拦截器方法也不执行,但是之前的after拦截方法会反序执行

12.异常处理

*SpringMVC使用HandlerExceptionResolver接口的实现类处理程序的异常,包括url映射异常、数据绑定异常、请求处理方法执行异常等

*这三个异常处理的实现类是由加载的,所以要使用这三个方法的话需要添加这个注解

*ExceptionHandlerExceptionResolver:处理用@ExceptionHandler注解修饰的方法,这个方法不是请求处理方法,而是异常处理方法

*@ExceptionHandler(value=Exception[]),发生了value数组中的异常用这个方法进行处理

*还可以给方法加一个Exception类型的入参,用来捕获异常信息

*如果想对异常信息进行回显即将该异常添加到请求域中以进行回显的话,不能添加Map类型的入参,应该返回一个ModelAndView类型的结果

*如果有一个异常可以被多个异常处理方法所捕获,该异常只能被最相对精确匹配的方法所捕获

*被@ExceptionHandler注解的方法只能处理这个控制器内部请求处理方法抛出的异常

*使用全局的@ExceptionHandler异常处理器

*专门编写一个类用来处理异常,这个类需要被@ControllerAdvice注解修饰

*编写由@ExceptionHandler修饰的方法即可

*如果在当前控制器中找不到对应的异常处理方法,则出去找

*ResponseStatusExceptionResolver:用来定制异常对应的错误代码和错误信息

*编写自己的Exception

*用@ResponseStatus(value=HttpStatus.**,reaseon="")修饰该异常,如果程序在运行的过程中抛出了这个异常,那在浏览器端现实的就是不是500(服务器内部错误),而是定制的异常代码和异常提示原因

*该注解还可以放到请求处理方法之上,如果注解了方法,该方法该怎么执行还怎么执行,只是无论方法是否抛出异常,执行了该方法就一定会响应错误,错误代码和错误原因提示为注解中定制的内容

*DefaultHandlerExceptionResolver:对一些特殊的异常进行处理

*用来处理异常,并且将Spring的Exception转换为http的状态码

*主要是Spring自己用的,将自己框架中的异常转换为http状态码

*SimpleMappingExceptionResolver:它将异常映射为视图名称,即当发生该异常时,转到响应的页面进行展示

*在Spring的配置文件中进行配置

*配置SimpleMappingExceptionResolver的bean

*配置入参value(page)

*这个异常解析器会自动地将异常添加到请求域对象中去,key为exceptionAttribute,默认为exception,但是也可以在上面的入参中配置这个参数指名将异常添加到请求域对象时使用的key的名字

77
关闭
先学习,后交费申请表
每期5位名额
在线咨询
免费电话
QQ联系
先学习,后交费
TOP
您好,您想咨询哪门课程呢?
关于我们
机构简介
官方资讯
地理位置
联系我们
0513-91107100
周一至周六     8:30-21:00
微信扫我送教程
手机端访问
南通科迅教育信息咨询有限公司     苏ICP备15009282号     联系地址:江苏省南通市人民中路23-6号新亚大厦三楼             法律顾问:江苏瑞慈律师事务所     Copyright 2008-