Spring Web MVC是一种基于Java的实现了Web MVC设计模式的要求驱动类型的轻量级Web框架,即利用了MVC架构模式的思想,将web层进行职责解耦,基于要求驱动指的便是利用要求-相应模型,框架的目的便是帮助我们简化开拓,Spring Web MVC也是要简化我们日常Web开拓的。
2.springmvc上风
清晰的角色划分:
前端掌握器(DispatcherServlet)
要求到处理器映射(HandlerMapping)
处理器适配器(HandlerAdapter)
视图解析器(ViewResolver)
处理器或页面掌握器(Controller)
验证器( Validator)
命令工具(Command 要求参数绑定到的工具就叫命令工具)
表单工具(Form Object 供应给表单展示和提交到的工具就叫表单工具)
分工明确
而且扩展点相称灵巧,可以很随意马虎扩展,虽然险些不须要;
无需继续API直接命令操作
由于命令工具便是一个POJO,无需继续框架特定API,可以利用命令工具直接作为业务工具;
与spring无缝衔接
和Spring 其他框架无缝集成,是其它Web框架所不具备的;
适配任意类作为处理器
可适配,通过HandlerAdapter可以支持任意的类作为处理器;
支持大略定制
可定制性,HandlerMapping、ViewResolver等能够非常大略的定制;
功能强大
功能强大的数据验证、格式化、绑定机制;
灵巧的单元测试
利用Spring供应的Mock工具能够非常大略的进行Web层单元测试;
更随意马虎的主题与国际化
本地化、主题的解析的支持,使我们更随意马虎进行国际化和主题的切换。
强大的jsp标签库
强大的JSP标签库,使JSP编写更随意马虎。
还有比如RESTful风格的支持、大略的文件上传、约定大于配置的左券式编程支持、基于表明的零配置支持等等。
二、springmvc运行事理
核心架构的详细流程步骤如下:
1.首先用户发送要求——>DispatcherServlet,前端掌握器收到要求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程掌握;
2.DispatcherServlet——>HandlerMapping,HandlerMapping将会把要求映射为HandlerExecutionChain工具(包含一个Handler处理器(页面掌握器)工具、多个HandlerInterceptor拦截器)工具,通过这种策略模式,很随意马虎添加新的映射策略;
3.DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的运用,从而很随意马虎支持很多类型的处理器;
4.HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView工具(包含模型数据、逻辑视图名);
5.ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为详细的View,通过这种策略模式,很随意马虎改换其他视图技能;
6.View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据构造,因此很随意马虎支持其他视图技能;
7.返回掌握权给DispatcherServlet,由DispatcherServlet返回相应给用户,到此一个流程结束。
更简流程影象:
用户发起要求到前端掌握器(Controller)
前端掌握器没有处理业务逻辑的能力,须要找到详细的模型工具处理(Handler),到处理器映射器(HandlerMapping)中查找Handler工具(Model)。
HandlerMapping返回实行链,包含了2部分内容: ① Handler工具、② 拦截器数组
前端处理器通过处理器适配器包装后实行Handler工具。
处理业务逻辑。
Handler处理完业务逻辑,返回ModelAndView工具,个中view是视图名称,不是真正的视图工具。
将ModelAndView返回给前端掌握器。
视图解析器(ViewResolver)返回真正的视图工具(View)。
(此时前端掌握器中既有视图又有Model工具数据)前端掌握器根据模型数据和视图工具,进行视图渲染。
返回渲染后的视图(html/json/xml)返回。
给用户产生相应。
三、框架组件
DispatcherServlet:前端掌握器
用户要求到达前端掌握器,它就相称于mvc模式中的c,dispatcherServlet是全体流程掌握的中央,由它调用其它组件处理用户的要求,dispatcherServlet的存在降落了组件之间的耦合性。
HandlerMapping:处理器映射器
HandlerMapping卖力根据用户要求找到Handler即处理器,springmvc供应了不同的映射器实现不同的映射办法,例如:配置文件办法,实现接口办法,表明办法等。
Handler:处理器
Handler 是继DispatcherServlet前端掌握器的后端掌握器,在DispatcherServlet的掌握下Handler对详细的用户要求进行处理。
由于Handler涉及到详细的用户业务要求,以是一样平常情形须要程序员根据业务需求开拓Handler。
HandlAdapter:处理器适配器
通过HandlerAdapter对处理器进行实行,这是适配器模式的运用,通过扩展适配器可以对更多类型的处理器进行实行。
View Resolver:视图解析器
View Resolver卖力将处理结果天生View视图,View Resolver首先根据逻辑视图名解析成物理视图名即详细的页面地址,再天生View视图工具,末了对View进行渲染将处理结果通过页面展示给用户。
View:视图
springmvc框架供应了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图便是jsp。
一样平常情形下须要通过页面标签或页面模版技能将模型数据通过页面展示给用户,须要由程序员根据业务需求开拓详细的页面。
解释:在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。
须要用户开放的组件有handler、view
四、springmvc与struts2不同
springmvc的入口是一个servlet即前端掌握器,而struts2入口是一个filter过虑器。
springmvc是基于方法开拓(一个url对应一个方法),要求参数通报到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开拓,通报参数是通过类的属性,只能设计为多例。
Struts采取值栈存储要乞降相应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request要求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView工具,末了又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认利用jstl。
五、springmvc与struts2有什么差异?
底层实现机制 matchstruts2:filter
springmvc:servlet
运行效率struts2:底层是Servlet,参数基于属性封装,如果配置单例,会涌现线程安全问题,以是配置多例
springmvc:底层是Servlet,单例
参数封装struts2:基于属性封装
springmvc:基于方法进行封装
六、入门案例
创建工程
导jar包
写好页面
创建Controller
创建springmvc.xml
在web.xml中配置前端掌握器
表明驱动的浸染:
自动创建处理器映射器自动创建处理器适配器支持所有表明支持json格式数据七、参数绑定
springmvc吸收参数办法:直接把吸收参数变量放在方法中自动吸收参数
1.办理参数乱码
get要求乱码:
1).再次编码
String(request.getParamter(“userName”).getBytes(“ISO8859-1”),”utf-8”)
2). server.xml设置 URIEncoding=”UTF-8”
post要求乱码:
1). 利用spring编码过滤器(web.xml),必须配置在前端掌握器之前.
2.吸收自定义参数
1).表明:@InitBinder:转换参数
2).自定义转换工具
在springmvc.xml中配置
3.默认支持的参数类型
1).HttpServletRequest:通过request工具获取要求信息
2).HttpServletResponse:通过response处理相应信息
3).HttpSession:通过session工具得到session中存放的工具
4).Model/ModelMap:ModelMap是Model接口的实现类,通过Model或ModelMap向页面通报数据.
model.addAttribute(\"大众item\公众, item);
页面通过${item.XXXX}获取item工具的属性值。
如果利用Model则可以不该用ModelAndView工具,Model工具可以向页面通报数据,View工具则可以利用String返回值替代。不管是Model还是ModelAndView,实在质都是利用Request工具向jsp通报数据。
5).绑定大略类型:当要求的参数名称和处理器形参名称同等时会将要求参数与形参进行绑定。从Request取参数的方法可以进一步简化。
4.支持的数据类型
参数类型推举利用包装数据类型,由于根本数据类型不可以为null
整形:Integer、int
字符串:String
单精度:Float、float
双精度:Double、double
布尔型:Boolean、boolean
5.吸收POJO
如果提交的参数很多,或者提交的表单中的内允许多的时候可以利用pojo吸收数据。哀求pojo工具中的属性名和表单中input的name属性同等。
如果是包装类型的POJO,包装工具.
页面定义:
Controller方法定义如下:
6.吸收数组
7.吸收list
标签中varStatus属性常用参数总结下:
八、springmvc表明
常用表明:
ControllerRequestMappingRequestParamRedirectForwardRequestBody/ResponseBody1.Controller
@Controller:用于标识是处理器类.表示把我的掌握器工具交给spring来创建。
Controller起浸染:只须要扫描即可。
2.RequestMapping
@RequestMapping :要求映射表明
用法举例:
@RequestMapping(“list.do”)@RequestMapping(“/list.do”)@RequestMapping(“list”)@RequestMapping(value=”list”)@RequestMapping(value=”list”,method.RequestMethod.POST)get要求:
所有从浏览器直接发送的要求,都是get要求href发送的要求都是get要求post:
表单提交是post要求ajax是post要求3.URL路径映射
@RequestMapping:要求到处理器功能方法的映射规则;
URL路径映射:@RequestMapping(value=”/user”)或@RequestMapping(“/user”)
RequestMethod要求方法限定
4.URL模板映射
@RequestMapping(value=\"大众/useredit/{userId}”):{×××}
占位符要求的URL可以是
“/useredit/001”或“/useredit/abc”,通过在方法中利用@PathVariable获取{×××}中的×××变量
实现restFul,所有的url都是一个资源的链接,有利于搜索引擎对网址收录。
多个占位符
如果有多个pojo、并且里面具有相同的属性,办理方案:
我们利用包装类来包装pojo、经由包装的pojo相称于加了一层包构造。所往后面纵然具有相同的属性也无所谓。
5.RequestParam
value:参数名字,即入参的要求参数名字,如value=“studentid”表示要求的参数区中的名字为studentid的参数的值将传入;
required:是否必须,默认是true,表示要求中一定要有相应的参数,否则将报400缺点码;
defaultValue:默认值,表示如果要求中没有同名参数时的默认值
@RequestParam(defaultValue=”1”,value=”myid”)
功能1:设置默认值
功能2:给参数定义别名,别名和页面通报参数匹配即可
6.Redirect
Contrller方法返回结果重定向到一个url地址.
同一个类内跳转redirect:add.do 与 redirect:/user/add.do” 在同一个类里面进行跳转。上面2个都可以实现跳转。但是有差异:第一个是同一个根路径下面跳转。第二个是在项目路径下进行跳转。
不同的类进行跳转不同的类进行跳转只能利用:redirect:/user/add.do进行跳转。即是从项目路径下来查询。
redirect办法相称于“response.sendRedirect()”,转发后浏览器的地址栏变为转发后的地址,由于转发即实行了一个新的request和response。
由于新发起一个request原来的参数在转发时就不能通报到下一个url,如果要传参数可以/user/userlist.do后边加参数,如下:
/user/userlist.action?groupid=2&…..
7.Forward
controller方法实行后连续实行另一个controller方法。
return “forward:/user/userlist.action”;
forward办法相称于
“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还是原来的地址。转发并没有实行新的request和response,而是和转发前的要求共用一个request和response。以是转发前要求的参数在转发后仍旧可以读取到。
8.json数据交互
@RequestBody表明用于读取http要求的内容(字符串),通过springmvc供应的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。
@RequestBody表明实现吸收http要求的json数据,将json数据转换为java工具
@RequestBody/@ResponseBody要依赖Jackson
支持表明,表明映射器和表明适配器可以利用代替。
默认注册了表明映射器和表明适配器等bean。
九、非常处理
springmvc在处理要求过程中涌现非常信息交由非常处理器进行处理,自定义非常处理器可以实现一个别系的非常处理逻辑。
1.自定义非常
全局非常解析接口 HandlerExceptionResolver
2.自定义非常处理器
3.新建缺点提示页面
略
4.非常处理器配置
在springmvc.xml中配置:
十、上传文件
采取跨做事器异步上传办法.
1.jar包
依赖:commons-io,commons-fileupload,jersey框架下的jar包
2.配置解析器
配置springmvc.xml
3.配置图片做事器权限
readonly
false
4.Controller编写
5.页面编写
十一、RESTful支持
Restful便是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
资源定位:互联网所有的事物都是资源,哀求url中没有动词,只有名词。没有参数
Url格式:
blog.dn.net/beat_the_wo…
资源操作:利用put、delete、post、get,利用不同方法对资源进行操作。分别对应添加、删除、修正、查询。
1.前端掌握器设置
2.静态资源访问
springmvc支持restFull风格软件架构模式:
没有扩展名没有?办法通报参数,参数都在url链接中springmvc供应url默认映射,映射:@RequestMapping(“/item/deitItem/{id}”)
通过@Pathvariable 映射参数通报十二、拦截器
Spring Web MVC 的处理器拦截器类似于Servlet 开拓中的过滤器Filter,用于对处理器进行预处理和后处理。
1.自定义拦截器
2.拦截器配置
在springmvc中配置
3.拦截器实行顺序
preHandle按拦截器定义顺序调用
postHandler按拦截器定义逆序调用
afterCompletion按拦截器定义逆序调用
postHandler在拦截器链内所有拦截器返成功调用
afterCompletion只有preHandle返回true才调用
4.拦截器与过滤器的差异
过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围大
拦截器Inerceptor依赖于框架容器,基于反射机制,只过滤要求
十三、ssm整合
掌握层采取springmvc、持久层利用mybatis实现.
1.需求
实现商品查询列表,从mysql数据库查询商品信息。
2.导jar包
包括:spring(包括springmvc)、mybatis、mybatis-spring整合包、数据库驱动、第三方连接池、日志等。
3.spring与mybatis整合
1).db.properties
2).log4j.properties
3).配置sqlMapConfig.xml
在classpath下创建mybatis/sqlMapConfig.xml
4).配置applicationContext.xml
5).配置ItemsMapper.xml
6).ItemsMapper.java
4.spring管理service
1).Service由spring管理。
2).spring对Service进行事务掌握。
service层代码:
5.spring与springmvc整合
1).配置springmvc.xml
2).web.xml
3).Controller编写
SpringMVC项目总结:
一、通过指定的url获取页面的html
1.为了避免中文乱码,须要实现指定jsp页面的编码为utf-8,但是如果碰着html页面的分外标签可能会产生一些部分中文乱码
更好的办理方案可以用jsonp
maven坐标如下:
二、SpringMVC框架里jsp客户端向做事端通报List类型的参数
客户端
做事端
吸收list数据
三.SpringMVC中的文件下载
四、基于iText和flying saucer结合freemark把html天生pdf (支持css样式)
项目地址:
git.oschina.net/lemonzone20…
考试测验了几个开源项目觉得这个效果最好,而且文旦详尽,须要把稳的是
1、不支持css3分外样式,html里如果有中文须要现在css样式里申明所用字体
2、项目里读取html时利用了freemark技能也但是我自己操作的时候利用总结一里的jsonp读取更加方便
五、把文件打包天生zip
六、图片上传到非工程文件夹下,希望通过该工程的url访问该图片
文件上传到tomcat下的工程下,项目重新启动图片就没了
办理的思路:
在配置文件下配置路径
BASE_FILEUPLOAD_URL=/upload/username/type/year/month/
BASE_FILEUPLOAD_PATH=../../upload/username/type/year/month/
上传文件时读取该路径并进行拼接:
//文件上传目录路径
String savePath = pageContext.getServletContext().getRealPath(“/”) + BASE_FILEUPLOAD_PATH;
这样配置往后图片就上传到tomcat的一级目录下了
定义访问的时候url为localhost:8080//btkjsite_designcloud/before/getFile/upload/username/type/year/month/20160911.jpg
先根据访问的url找到图片的实际物理路径,再通过输入流读取文件,写入输出流在网页上把图片显示出来
企业事情实践SpringMVC总结
一:配置SpringMVC开拓环境任何mvc的框架,都是须要在web.xml中进行核心的配置的,struts2是一个过滤器,而SpringMVC则是一个servlet,但是配置方法大同小异,都是在web.xml中进行配置,配置方法如下:
再然后便是配置springMVC-servlet.xml,这个文件名之前说过,可以自定义路径与名称,如果不自定义,则一定要放在WEB-INFO下,把稳引入精确的命名空间,然后加入核心分解解析器,便是解析url的要求,类似于stuts的配置文件,配置如下:
然后便是正式利用SpringMVC了,我们常日是用表明的办法,由于表明真的太好用了,省事好多,但是这里也大略先容一下利用xml配置文件的办法来写一个大略的helloworld
1.1.配置文件的helloworld
首先新建一个类,这个类要实现Controller接口,然后实现它的一个ModelAndView方法,代码如下:
然后在springMVC-servlet.xml中配置一个bean:配置方法如下:
这种配置和struts2实在是一样的,name属性便是浏览器要求的url,而class便是它处理的类,而运行的方法,便是上面所继续的接口,然后在浏览器输入http://localhost:8080/springMVC/test,就可以跳转到welcome.jsp下,这是根据之前配置的视图分解解析器的前后缀前该方法返回的字符串拼接而成的。
1.2.基于表明的helloworld
利用表明就要大略得多了,首先是在springMVC-servlet.xml中配置扫描的包,这样spring就会自动根据表明来描述一些特定的表明,然后把这些bean装载进入spring容器中,配置如下:
然后,在指定的包,或者其子包下新建一个类,代码如下:
这样就不用再写配置文件,只要加上相应的表明就行,比如说这里的helloworld方法,只要在浏览器输入http://localhost:8080/project/hellowrold,就可以进入spring.jsp页面
二:@RequestMapping详解2.1.类的@RequestMapping表明
刚才看到了@RequestMapping这个表明是用于给一个方法加上url的要求地址,不过,这个表明不仅仅可以加在方法上面,也可以加在类上面,代码如下图所示:
如上代码如示,如果同时在类与方法上面同时加上@RequestMapping表明的话,那么URL肯定不会是之前的那种写法了,现在要写成类的表明加上方法的表明,便是有点类似struts2中,的nameplace属性,那如如上代码,URL该当为http://localhost:8080/project/springMVC/testReuqestMapping
2.2.要求办法的设置
像我们平常提交一个表单,肯定会有get,与post这两个常用的要求,那么在springMVC中要如何设置呢?很大略,也是在@RequestMapping中利用,不过须要在方法的表明上面利用,代码如下:
这下在from表单中,或者异步要求中,就须要以post做为要求,不然会报错的,由于这里已经设置为了post,如果客户端再要求get,将会报错。
2.3.参数的规定与要求头的规定设置
我们都知道http要求会有着要求参数与要求头,那么在springMVC里面,是可以规范这些信息的,首先给一段代码示例:
无论是params,还是headers,都可以包含多个参数,以逗号相隔就行,如果不知足写了的条件,则就会报错,不许可要求资源。其次这两个属性还支持一些大略的表达式:
2.4.@RequestMapping映命中的通配符
在@RequestMapping的value属性中,还支持Ant格式的能配符:
/user//createUser 匹配/user/abcd/createUser
/user//createUser 匹配/user/aa/bb/cc/createUser
/user/?/createUser 匹配/user/a/createUser
这里就不作代码演示了,相信大家一看就懂,由于这种通配符真的太常见了
2.5.@RequestMapping与@PathVariable表明的一起利用
springMVC很灵巧,它可以获取URL地址中的值,然后当作变量来输出,这里要利用@PathVariable表明,故名思意,便是路径变量的意思,常日的话,@PathVariable要利用,是一定要与@RequestMapping一起利用的,下面给出代码示例:
先在括号中加上表明,个中value便是@RequestMapping中占位符的声明,然后加上数据类型和定义的变量,这样就可以对其进行利用了
2.6.Rest风格的URL
常日的话,表单有着post,与get提交办法,而rest风格的URL,则有着get,post,put,delete这四种要求办法,但是浏览器却是只支持get与post,以是我们可以利用springMVC,把它进行转换,我们要利用org.springframework.web.filter.HiddenHttpMethodFilter这个类,这是一个过滤器,我们首先要在web.xml中配置它,请配置在第一个位置,不然的话,可能会前辈入其它的过滤器,配置代码如下:
如上的配置,这个过滤器则会拦截所有的要求,我们可以看一下org.springframework.web.filter.HiddenHttpMethodFilter的部分源代码:
当这个过滤器拦截到一个要求时,就会先拿到这个要求的参数,它要知足两个条件,第一,浏览器发出的要求为post请示,第二,它还要有一个参数,参数名为_method,而它的值,则可以为get,post,delete,put,此时过滤器就会把post要求转换成相应的要求,不然的话就不进行转换,直接要求。至于添加_method参数的话,则可以利用hidden隐蔽域,或者利用?拼接参数都可以。
下面就该是掌握器的方法了,在本处第2小点中,有讲到@RequestMapping的要求办法的设置,只要把这个要求办法设置成对应的要求就行,比如说转换成了DELETE要求,则@RequestMapping也要写成对应的DELETE要求,不然会出错,示例代码如下:
此时,就可以精确转换要求办法了。
三:获取http要求中的信息3.1.获取要求中的参数,@RequestParam
在获取类似这种:http://localhost:8080/project/test?user=a&password=2这种要求参数时,就须要用@RequestParam这个表明来获取,代码如下:
如上面注释所写,它常用这三个属性,value是参数名,但是如果只写了参数名的话,要求时,就必须带此参数,不然就会报错。如果把required属性设置为false,就可以使得该参数不传,还有defaultValue属性,此属性可以当浏览器没有传此参数时,给这个参数一个默认值
3.2.获取要求头的信息,@RequestHeader
之前也有提到过http的要求头的信息,那么这里就可以利用@RequestHeader表明来获取要求头的信息,它的利用方法与上面的@RequestParam是完备一样的,同样拥有value,requied,defaultValue这三个属性,而有代表的浸染也是一样的,下面给出代码示例:
由于它的用法与本章第一点的获取要求参数的用法一样,以是这里就不作过多的解释,详细可以查看@RequestParam的用法
3.3.获取Cookie的信息,@CookieValue
在开拓中,有很多情形都会用到Cookie,这里可以利用@CookieValue表明来获取,其利用方法与@RequestParam与@RequestHeader一样,这里就不过多阐述,给出示例代码:
它也有着三个属性,value,required,defaultValue,分别对应Cookie名,是否非空,默认值。
3.4.利用Pojo来获取要求中的大量参数
如果http要求中只有一两个参数,那么利用@RequestParam还可以,但是如果一个要求中带有着大量的参数,那么这样就有点麻烦了,那么springMVC就可以利用Pojo工具来获取这次要求中的所有参数,并且全部封装到这个工具里面,这种办法类似struts2的ModelDriver,相信利用过struts2的同学都清楚,这种办法极其简便,下面一边给代码,一边阐明,首先给出要求的处理方法:
这里无需利用其它的表明,只须要在这个处理方法中加上一个类就行,那么springMVC就会自动把要求参数封装到你写好的类中,而且这种封装还支持级联操作,什么是级联操作呢?便是User类中的属性还有着其余的一个类,下面给出User类的代码:
由上面可见,个中不仅有普通的属性,还有着一个Address的类,我们再来看一下Address类的代码:
可以很清楚的看清User类与Address类的关系,那么像这种关系的工具,在浏览器form表单中的name属性该如何写呢?Address类中的字段,要加上address,比如address.province,或者address.city,其它的属性,就直接写User类中的属性就可以了。而这里为什么Address变成了小写的呢?实在这并不是什么命名规则,而是我在User类中便是这么定义的
这下没有什么问题了吧,我们再来看一下浏览器表单是怎么写的:
如上表单元素就可以看到表单的name属性是如何与User类对应的,其Address类中的属性,就以address.city。
下面来说一下这种要求办法的特点:
1.简便,不须要大量的@RequestParam表明。
2.与struts2的ModelDriver的用法差不多,只不过ModelDriver是接口,全体类里面所有的方法都可以利用。而springMVC中这个Pojo工具的浸染仅仅是当前的处理方法中。
3.这种Pojo的利用中,浏览器的参数可以为空,便是可以不传参数,也不会报错,不像@RequestParam,如果不指定requried=false的话,还会报错。
四:Servlet原生API4.1.利用Servlet原生API
在我们平常利用springMVC中,虽然说springMVC已经帮我们做了很多事情了,但是我们实际中还是会要用到Servlet的原生API,那这个时候要如何得到Servlet的原生工具呢?这里与struts2不同,springMVC是在方法中声明对应的参数来利用这些工具,而struts2则是调用相应的方法来得到这些工具。当然,对付没有学过struts2的同学,可以忽略,下面给出代码示例:
如上代码所示,直接在对应的处理方法里面声明这些须要利用的工具就可以了,那如果同时要利用Pojo来得到要求参数怎么办呢?这个不用担心,照常利用就行了,如上代码所示,同样声明了一个User类来吸收参数,并不会有任何的影响。
4.2.利用Servlet原生API的事理(部分springMVC的源代码)
如果你想问,springMVC中的处理方法,里面可以支持哪些Servlet的原生API工具呢?或者你又想问,为什么可以照常的利用Pojo来获取要求参数呢?那么这里,我们先来看一下springMVC的源代码,然后再作阐明:
从这里就可以解释了一个问题了,springMVC首先会通过反射技能得到这个方法里面的参数(源代码没有贴上,有兴趣的可以自行查看springMVC的源代码),然后比较这些参数的类型,是否与上面的九个类型想匹配,如果匹配成功,则返回这个工具,请把稳,是与工具类型相匹配,而不是与形参名作匹配,以是这样,就不会使得Pojo无法事情了
4.3.springMVC支持哪些原生API
实在从4.2中的源代码中也是可以看到了,这里支持九种个工具,对应关系分别是:
五:页面中的传值5.1.大略的利用ModelAndView来向页面通报参数
实际开拓中,总要大量的向页面中通报后台的数据,那么存放数据的方法也有多种多样,比如说存到request中,大家都知道是利用request.setAtrribute()来向request域中通报值,但是实际上springMVC给我们封装了更好的方法,那便是利用ModelAndView。
首先,方法的返回值,该由String变成ModelAndView,然后在处理方法中new一个ModelAndView工具,然后返回这个工具就可以了,工具中可以增加返回页面的字符,也可以向这个工具里面通报参数,现在给出一个大略的示例代码:
如上代码如示,我们可以利用布局方法给它传一个值,那便是它终极要返回的页面的值,或者利用setViewName方法来给它一个返回页面的名字。利用addObject方法来给这个模型添加数据,这是一个键值对的数据,然后返回这个ModelAndView工具。
5.2.利用参数Map来向页面传值
可以在实行方法中定义一个Map参数,然后在方法中,向map添加内容,然后在页面中根据map的键来取对应的值,也是存在request域中,下面给出代码示例:
这里面便是在方法中有着一个Map类型的参数,实在不仅仅可以是Map类型,还可以是Model与ModelMap类型的,由于终极传入的根本就不是Map,而是
org.springframework.validation.support.BindingAwareModelMap
5.3.利用@SessionAttributes表明,把值放到session域中
实在5.1和5.2所诉的内容,虽然是把后台数据通报到前台,但是全部都是放置到request域中,这里讲诉一下利用@SessionAtrributes表明,把后台数据同时放到session中。
首先先容一下这个表明,这个表明只能放在类上面,而不能放在方法上面。它有两个属性,一个是value属性,一个是types属性,这两个数据都是数组,以是可以声明多个,实在不论是value属性,还是types属性,都可以把数据同时放到session域中,只不过value属性对应的是实行方法中的map凑集的键,只假如对应的键,那么其值,也会同时被通报到session域中(这里之以是加上“同时”这个词,是由于它会同时存到request与session中),而types属性,则是放置类的凑集,只要map凑集中存的是该类的数据,则也会同时被放到request中,下面给示例代码:
如上代码所示,先是在类上面利用了@SessionScope表明,然后同时利用了value与types属性,第一个value属性的值”user”,则是testSessionAtrributes方法中map凑集中的”user”的键,以是这一个键值对会被同时放入session域中,而第二个types的属性中的String.class,则是代表着这个类了,意思便是说,只假如map凑集中放的String类型的数据,都会被放到session中。
把稳:利用了value属性后,这个属性也就必须存在,意思便是说,必须有一个map,然后有一个user的键,不然会报错,当然,这个是可以办理的,后面会详细讲到。
5.4.@SessionAtrribute引发的非常
上一讲说到利用@SessionAtrribute来润色一个类,就可以把一些值存放到session域中,但是如果找不到对应的值,就会报非常,这里可以用@ModelAtrribute来进行润色,对它改名就可以了,代码如下:
或者加上一个有着@ModelAtrribute所润色的方法,至于@ModelAtrribute表明,将会在第六章讲到。
六:@ModelAtrribute表明详解6.1.大略先容@ModelAtrribute及其运行流程
在我们开拓中,会有这样一种情形,比如说我要修正一个人的信息,但是用户名是不让修正的,那么我在浏览器页面中肯定会有一个表单,里面有一个隐蔽域的id,可以改密码,可以改邮箱,但是用户名不让修正,以是我们不能给用户名的输入框,然后用户修正完数据后,点击提交保存,然后创造这个时候用户名不见了!
当然大家都会想到便是重新取出用户名,然后给这个工具赋值,或者先从数据库里面找到这个用户的工具,然后再来修正这个工具,而不是自己来创建工具,@ModelAtrribute表明便是基于这种情形的。
那么这种情形在springMVC中要如何实现呢?
首先给出实行的目标方法的代码:
这个代码很大略,只是利用Pojo来获取表单的参数,但是User类是不可能从表单得到用户名的,以是这个类就短缺了一个属性,如果这样存到数据库里面,是肯定要出问题的,那么按照之前所说,我们可以先得到这个User工具,然后给这个工具赋值,但是我们有着简化的方法,下面给出@ModelAtrribute表明的用法:
可以创造,上面的类是没有返回值的,但是经有一个map凑集,我们把这个从数据库查出来的user工具放到了Map凑集中,然后就不须要做什么了,然后上面的
testModelAtrribute方法实行的时候,就会自动把用户名给添补进去。
下面讲一个@ModelAtrribute表明的实行流程
1.实行@ModelAtrribute表明润色的方法:从数据库中取出工具,并把工具放到了Map中,键为user
2.springMVC从Map凑集中取出User工具,并把表单的要求参数赋值给user工具相应的属性
3.springMVC把上述工具传入目标方法的参数
4.这个user工具是存在request中,如果jsp表单中有对应的字段,还会自动添补表单
把稳:在@ModelAtrribute润色的方法中,放入Map时的键要和目标方法的参数名同等
6.2.@ModelAtrribute源代码剖析
可以一边调试一边查看源代码,这里的源代码有点多,我就不贴出来了,有兴趣的同学可以自己看,我这里讲诉一下事理:
1.调用@ModelAtrribute表明润色的方法,实际上是把@ModelAtrribute中的Map放到了implicitModel中。
2.解析要求处理器的标参数,实际上目标参数来自于WebDataBinder工具的target属性
(1).创建WebDataBinder工具
确定objectName属性,若传入的attrName属性为”“,则objectName为类名第一个字母小写
把稳:atrributeName,若目标方法的Pojo属性利用了@ModelAtrribute表明来润色,则atrributeName值即为@ModelAtrribute的value属性值
(2).确定target属性
>在implicitModel中查找atrrName对应的属性值,若存在ok,若不存在,则验证Hander,是否利用了@SessionAtrributes进行润色,若利用了,则考试测验从session中获取attrName所对应的属性值,若session中没有对应的值,则抛出非常
>若Hander没有利用@SessionAtrributes进行润色,或@SessionAtrributes中没有利用value值指定的键和attrName相互匹配,则通过反射创建了Pojo工具,这个时候target就创建好了。
3.springMVC把表单的要求参数赋给了WebDataBinder的target属性
4.springMVC会把WebDataBinder的attrName和target给到implicitModel
5.把WebDataBinder的target作为参数通报给目标方法的入参
6.3.办理@ModelAtrribute表明中,map凑集的键与实行目标方法的参数名不一致的情形
实在我们可以在目标方法里面的参数中,定义一个@ModelAtrribute表明,并把其值指定为@ModelAtrribute表明润色的方法中的map的键,下面给出代码示例:
可以看到,目标方法的参数中,有着@ModelAtrribute润色,其value属性为”abc”,再来看一下@ModelAtrribute所润色的方法:
在这里就可是很显示的看到map是存放了一个”abc”的键。
七:转发与重定向7.1标签
在springMVC的配置文件中利用标签可以使得url不须要进入handler处理方法,就可以直接跳转页面,配置方法如下
根据如上的配置,就可以直接在浏览器中输入http://localhost:8080/project/good,就可以跳转至success.jsp页面,而无需进入handler处理方法,更不须要进行@RequestMapping映射。
但是如果仅仅是这样的配置,会有一个很大的问题,便是之前所写的handler处理方法全部都不能利用了,全部会进行报错,那么要怎么办理呢?可以在springMVC的配置文件中,写一个下面的标签,就不会有这样的问题了:
只要写上这样的一个标签,那么就可以办理上面的问题,而且也不要写任何参数。不过这个标签详细有什么用呢?后面会作先容。
7.2.自定义视图
下面来讲一下自定义视图,利用它可以很好的和jfreechar或excel整合,下面来详细解释。
首先新建一个视图,新建一个类,继续view接口,然后覆盖里面的方法,代码如下:
如上所示,写一个类,继续View接口,然后覆盖里面的方法,就可以自己自定义视图了,但是目前这个视图还没有用,须要在springMVC的配置文件中进行配置,才能利用这个视图,配置方法如下:
只要在springMVC的配置文件中写如上的配置,那么这个视图就可以利用了,然后我们写一个handler处理方法,代码如下:
然后的话,我们输入如下url,http://localhost:8080/project/testView,就不会进行helloView.jsp,由于配置的解析视图的order值为最高,也就代表着它的优先级是最低的,以是会先实行我们自定义的视图,那么就会在浏览器中显示之前视图中向浏览器写的数据。
7.4.视图的重定向操作
上面所说的全部都是视图的转发,而不是重定向,这次我来讲一下重定向是怎么操作的。
只要字符串中以forward或者redirect开头,那么springMVC就会把它解析成关键字,然后进行相应的转发,或者重定向操作,下面给出示例代码:
上面就分别是重定向与转发操作,实在不止java代码,标签中的返回视图,也可以加上redirect或者forward字符串,也会进行相应的操作。
八:数据的格式化8.1 日期格式化
form表单向后台处理方法提交一个参数的时候,如果提交一个日期的数据,而后台吸收的数据类型则是Date类型,那么springMVC肯定无法将其转换成,由于springMVC不知道你传的数据的格式是怎么样的,以是须要为吸收的字段指定日期的格式,利用@DateTimeFormat表明,利用方法如下:
利用条件:须要在springMVC-servlet.xml的配置文件中配置,这个在开拓中肯定会配置的,由于它有好多浸染,如果不配置,则下面代码无效:
下面是目标方法的代码:
上面便是在吸收的参数前面加了一个@DateTimeFormat表明,表明中写明pattern属性,写上日期的格式,然后在浏览器输入:http://localhost:8080/project/dateFormat?date=19951029,这样springMVC就可以把这个字符串转成Date日期了。
如果是利用Pojo,利用一个工具来吸收参数,那么也是一样的,同样是在字段的上方,加上一个@DateTimeFormat表明,如下:
8.2.数字的格式化
除了日期的格式化,我们可能还会碰着数字的格式化,比如司帐职员作账时,数字喜好这样写 1,234,567.8 由于这样大略明了,但是如果由java直接来解析的话,肯定是弗成的,由于这根本就不是一个Float类型的数据,肯定是要报错的,那么要如何呢?我们可以利用@NumberFormat()表明,这个表明的利用办法,和利用条件和8.1章节,日期的格式化是一样的,请先查看8.1章节,再看本章。
和之前一样,是肯定要配置的,不过这里就不详细解释了,下面给出实行方法的代码:
其利用方法,实在是和@DateTimeFormat是一样的,但是这里的参数有必要解释一样,”#“是代表数字,那么这个时候,就可以对其进行解析了。如果你传入的是一个精确的Float类型的数据,那么它会被精确的吸收这个数字,如果不是一个Float类型的数据,那么springMVC会考试测验利用@NumberFoamat表明的参数来考试测验解析。
如输入的是http://locathost:8080/project?num=123,那么springMVC会解析成123.0,如果是http://locathost:8080/project?num=123.1,则会正常显示成123.1,那如果是http://locathost:8080/project?num=1,234,567.8这种分外的写法,则也会精确的解析成1234567.8
8.3.数据的校验
数据的考验是利用Hibernate-validator的扩展表明,它是javaee6.0提出的JSR303的实现,利用它,可以用表明对数据进行校验,下面来说一下利用方法。
1.首先要导入jar包,这不是spring的jar包,须要下载Hibernate-validator的jar包,然后添加到项目工程中
2.其次是要在springMVC的配置文件中,即springMVC-servlet.xml中配置,不须要写其它的属性:
3.然后在字段面前加上对应的校验表明,下面以一个bean作一个大略的例子:
这样就会对利用了表明的字段进行校验,然后这样还弗成,还须要指定目标实行方法,以是须要在实行方法上面也加上一个表明@Valid,这样加了这个表明的实行方法就会校验数据,下面给出目标方法的表明:
只要在这个方法上面加上@Valid表明,然后这个实行方法就会校验数据,校验的结果可以利用BindingResult工具显示,这个工具会不仅仅会保存数据校验的结果,还会保存数据类型转换的结果,以是都可以利用这个工具得到相应的信息,显示的方法如下面的代码如示。
把稳:须要校验的bean工具与其绑定结果工具或缺点工具是成对涌现的,他们中间不许可声明其它的参数
8.4.JSR303的验证类型
通过上面的例子我们知道可以利用表明来验证数据类型,但是详细可以利用哪些表明呢,下面给出解释:
8.5.通报json类型的数据
而在springMVC中,利用json非常的大略,但是首先须要引进其它的一些jar包,那便是jackson,这是一个解析json的jar包,然后就可以直策应用了,下面给出代码示例:
如上如示,只要在实行方法的上面加上@ResponseBody表明,然后定义目标方法的返回值,其返回值可以是任意凑集,也可以是任意工具,然后springMVC会自动将其转换成json
8.6.文件上传
springMVC也封装了文件上传,变的极其大略,但是须要引入common-io.jar与common.upload.jar包,然后须要在spinrgMVC-serlvet.xml中作如下的配置:
把稳:id必须如上写法,不然会报错
然后给出处理方法的代码:
如果是多个文件上传,则改为数组,如果是单个,办法也是一样,与struts2的文件的上传极其的类似。
九:拦截器9.1.第一个拦截器
编写拦截器极其大略,只要编写一个类,实现HandlerInterceptor的方法,然后在springMVC的配置文件中配置这个类,就可以利用这个拦截器了。
首先给出配置文件的写法:
然后再来写FirstInterceptor这个拦截器,代码如下:
然后在每个实行方法调用之前,都会前辈拦截器,这便是一个大略的拦截器的写法了。
9.2.拦截器的指定例模
在利用拦截器时候,并不一定要对所有的目标方法都进行拦截,以是我们可以只对指定的方法进行拦截,这就须要变动配置文件了,下面给出配置文件的写法:
只须要在中配置一个,然后指定其路径,就可以了,这个路径可以指定一个URL,也可以利用通配符。
9.3.拦截器的利用顺序
当同时定义了多个拦截器的时候,那么它的利用顺序是怎么样的呢?
preHandle是按配置文件中的顺序实行的
postHandle是按配置文件中的倒序实行的
afterCompletion是按配置文件中的倒序实行的