文章越日后越是精华css
1、SpringMvc介绍html
1.什么是springmvc前端
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即便用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助咱们简化开发,Spring Web MVC也是要简化咱们平常Web开发的。java
2.springmvc优点mysql
清晰的角色划分:css3
前端控制器(DispatcherServlet)git
请求处处理器映射(HandlerMapping)程序员
处理器适配器(HandlerAdapter)web
视图解析器(ViewResolver)ajax
处理器或页面控制器(Controller)
验证器( Validator)
命令对象(Command 请求参数绑定到的对象就叫命令对象)
表单对象(Form Object 提供给表单展现和提交到的对象就叫表单对象)
分工明确
并且扩展点至关灵活,能够很容易扩展,虽然几乎不须要;
无需继承API直接命令操做
因为命令对象就是一个POJO,无需继承框架特定API,可使用命令对象直接做为业务对象;
与spring无缝衔接
和Spring 其余框架无缝集成,是其它Web框架所不具有的;
适配任意类做为处理器
可适配,经过HandlerAdapter能够支持任意的类做为处理器;
支持简单定制
可定制性,HandlerMapping、ViewResolver等可以很是简单的定制;
功能强大
功能强大的数据验证、格式化、绑定机制;
灵活的单元测试
利用Spring提供的Mock对象可以很是简单的进行Web层单元测试;
更容易的主题与国际化
本地化、主题的解析的支持,使咱们更容易进行国际化和主题的切换。
强大的jsp标签库
强大的JSP标签库,使JSP编写更容易。
还有好比RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。
2、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)返回。
给用户产生响应。
3、框架组件
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
4、springmvc与struts2不一样
springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,能够设计为单例或多例(建议单例),struts2是基于类开发,传递参数是经过类的属性,只能设计为多例。
Struts采用值栈存储请求和响应的数据,经过OGNL存取数据, springmvc经过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据经过reques域传输到页面。Jsp视图解析器默认使用jstl。
5、springmvc与struts2有什么区别?
1. 底层实现机制 match
struts2:filter
springmvc:servlet
2. 运行效率
struts2:底层是Servlet,参数基于属性封装,若是配置单例,会出现线程安全问题,因此配置多例
springmvc:底层是Servlet,单例
3. 参数封装
struts2:基于属性封装
springmvc:基于方法进行封装
6、入门案例
建立工程
导jar包
写好页面
建立Controller
建立springmvc.xml
在web.xml中配置前端控制器
注解驱动的做用:
1. 自动建立处理器映射器
2. 自动建立处理器适配器
3. 支持全部注解
4. 支持json格式数据
7、参数绑定
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属性经常使用参数总结下:
8、springmvc注解
经常使用注解:
1. Controller
2. RequestMapping
3. RequestParam
4. Redirect
5. Forward
6. RequestBody/ResponseBody
1.Controller
@Controller:用于标识是处理器类.表示把个人控制器对象交给spring来建立。
Controller起做用:只须要扫描便可。
2.RequestMapping
@RequestMapping :请求映射注解
用法举例:
1. @RequestMapping(“list.do”)
2. @RequestMapping(“/list.do”)
3. @RequestMapping(“list”)
4. @RequestMapping(value=”list”)
5. @RequestMapping(value=”list”,method.RequestMethod.POST)
get请求:
1. 全部从浏览器直接发送的请求,都是get请求
2. href发送的请求都是get请求
post:
1. 表单提交是post请求
2. 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。
9、异常处理
springmvc在处理请求过程当中出现异常信息交由异常处理器进行处理,自定义异常处理器能够实现一个系统的异常处理逻辑。
1.自定义异常
全局异常解析接口 HandlerExceptionResolver
2.自定义异常处理器
3.新建错误提示页面
略
4.异常处理器配置
在springmvc.xml中配置:
10、上传文件
采用跨服务器异步上传方式.
1.jar包
依赖:commons-io,commons-fileupload,jersey框架下的jar包
2.配置解析器
配置springmvc.xml
3.配置图片服务器权限
readonly
false
4.Controller编写
5.页面编写
11、RESTful支持
Restful就是一个资源定位及资源操做的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
资源定位:互联网全部的事物都是资源,要求url中没有动词,只有名词。没有参数
Url格式:
http://blog.dn.net/beat_the_world/article/details/45621673
资源操做:使用put、delete、post、get,使用不一样方法对资源进行操做。分别对应添加、删除、修改、查询。
1.前端控制器设置
2.静态资源访问
springmvc支持restFull风格软件架构模式:
1. 没有扩展名
2. 没有?方式传递参数,参数都在url连接中
3. springmvc提供url默认映射,映射:
@RequestMapping(“/item/deitItem/{id}”)
4. 经过@Pathvariable 映射参数传递
12、拦截器
Spring Web MVC 的处理器拦截器相似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
1.自定义拦截器
2.拦截器配置
在springmvc中配置
3.拦截器执行顺序
preHandle按拦截器定义顺序调用
postHandler按拦截器定义逆序调用
afterCompletion按拦截器定义逆序调用
postHandler在拦截器链内全部拦截器返成功调用
afterCompletion只有preHandle返回true才调用
4.拦截器与过滤器的区别
过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围大
拦截器Inerceptor依赖于框架容器,基于反射机制,只过滤请求
十3、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项目总结:
1、经过指定的url获取页面的html
1.为了不中文乱码,须要实现指定jsp页面的编码为utf-8,可是若是遇到html页面的特殊标签可能会产生一些部分中文乱码
更好的解决方案能够用jsonp
maven坐标以下:
2.
2、SpringMVC框架里jsp客户端向服务端传递List类型的参数
客户端
服务端
接收list数据
三.SpringMVC中的文件下载
4、基于iText和flying saucer结合freemark把html生成pdf (支持css样式)
项目地址:
http://git.oschina.net/lemonzone2010/doc-render
尝试了几个开源项目感受这个效果最好,并且文旦详尽,须要注意的是
一、不支持css3特殊样式,html里若是有中文须要如今css样式里申明所用字体
二、项目里读取html时使用了freemark技术也可是我本身操做的时候利用总结一里的jsonp读取更加方便
5、把文件打包生成zip
6、图片上传到非工程文件夹下,但愿经过该工程的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原生API
4.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是按配置文件中的倒序执行的