springmvc概述
SpringMvc介绍
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
springmvc优点
1、清晰的角色划分:前端控制器(DispatcherServlet)、请求到处理器映射(HandlerMapping)、处理器适配器(HandlerAdapter)、视图解析器(ViewResolver)、处理器或页面控制器(Controller)、验证器( Validator)、命令对象(Command 请求参数绑定到的对象就叫命令对象)、表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要;
3、由于命令对象就是一个POJO,无需继承框架特定API,可以使用命令对象直接作为业务对象;
4、和Spring 其他框架无缝集成,是其它Web框架所不具备的;
5、可适配,通过HandlerAdapter可以支持任意的类作为处理器;
6、可定制性,HandlerMapping、ViewResolver等能够非常简单的定制;
7、功能强大的数据验证、格式化、绑定机制;
8、利用Spring提供的Mock对象能够非常简单的进行Web层单元测试;
9、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
10、强大的JSP标签库,使JSP编写更容易。
还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。
springmvc运行原理
核心架构的具体流程步骤如下:
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
执行处理器(Controller,也叫后端控制器)。
5、Controller执行完成返回ModelAndView
6、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
7、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
8、ViewReslover解析后返回具体View
9、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
10、DispatcherServlet响应用户
框架组件
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有什么区别?
- 底层实现机制
struts2:filter
springmvc:servlet - 运行效率
struts2:底层是Servlet,参数基于属性封装,如果配置单例,会出现线程安全问题,所以配 置多例
springmvc:底层是Servlet,单例 - 参数封装
struts2:基于属性封装
springmvc:基于方法进行封装
注解驱动的作用:
- 自动创建处理器映射器
- 自动创建处理器适配器
- 支持所有注解
- 支持json格式数据
参数绑定
springmvc接收参数方式:直接把接收参数变量放在方法中自动接收参数
解决参数乱码
get请求乱码:
- 再次编码,String(request.getParamter(“userName”).getBytes(“ISO8859-1”),”utf-8”)
- server.xml设置 URIEncoding=”UTF-8”
post请求乱码:
- 使用spring编码过滤器(web.xml),必须配置在前端控制器之前.
默认支持的参数类型
HttpServletRequest:通过request对象获取请求信息
HttpServletResponse:通过response处理响应信息
HttpSession:通过session对象得到session中存放的对象
Model/ModelMap:ModelMap是Model接口的实现类,通过Model或ModelMap向页面传递数据.
支持的数据类型
参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
整形:Integer、int
字符串:String
单精度:Float、float
双精度:Double、double
布尔型:Boolean、boolean
springmvc注解
常用注解:
- Controller
- RequestMapping
- RequestParam
- Redirect
- Forward
- RequestBody/ResponseBody
Controller
@Controller:用于标识是处理器类.表示把我的控制器对象交给spring来创建。
Controller起作用:只需要扫描即可。
RequestMapping
@RequestMapping :请求映射注解
get请求:
- 所有从浏览器直接发送的请求,都是get请求
- href发送的请求都是get请求
post请求: - 表单提交是post请求
- ajax是post请求
URL路径映射
@RequestMapping:请求到处理器功能方法的映射规则;
URL路径映射:@RequestMapping(value=”/user”)或@RequestMapping(“/user”)
RequestMethod请求方法限定
URL模板映射
@RequestMapping(value=”/useredit/{userId}”):{×××}占位符,请求的URL可以是“/useredit/001”或“/useredit/abc”,通过在方法中使用@PathVariable获取{×××}中的×××变量
RequestParam
value:参数名字,即入参的请求参数名字,如value=“studentid”表示请求的参数区中的名字为studentid的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报400错误码;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值
@RequestParam(defaultValue=”1”,value=”myid”)
功能1:设置默认值
功能2:给参数定义别名,别名和页面传递参数匹配即可
Redirect 重定向
redirect方式相当于“response.sendRedirect()”,转发后浏览器的地址栏变为转发后的地址,因为转发即执行了一个新的request和response。
由于新发起一个request原来的参数在转发时就不能传递到下一个url,如果要传参数可以/user/userlist.do后边加参数,如下:
/user/userlist.action?groupid=2&……
Forward 转发
forward方式相当于“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还是原来的地址。转发并没有执行新的request和response,而是和转发前的请求共用一个request和response。所以转发前请求的参数在转发后仍然可以读取到。
json数据交互
@RequestBody 注解 用于读取http请求的内容(字符串),通过springmvc提供的 HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到
controller方法的参数上。
@RequestBody 注解实现接收http请求的json数据,将json数据转换为java对象
@RequestBody/@ResponseBody要依赖Jackson
支持注解,注解映射器和注解适配器可以使用<mvc:annotation-driven />代替。
@ResponseBody 注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端
自定义异常处理器
/**
* 自定义全局异常处理器
*/
public class ExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object obj,
Exception ex) {
CustomException ce = null;
//判断此异常是否是自定义异常
if (ex instanceof CustomException) {
//自定义异常
ce = (CustomException) ex;
} else {
//如果抛出的不是系统自定义异常则重新构造一个系统错误异常
ce = new CustomException("网络异常!");
}
//创建modelAndView对象,封装数据,视图页面
ModelAndView modelAndView = new ModelAndView();
//设置数据
modelAndView.addObject("error", ce.getMessage());
//设置返回页面
modelAndView.setViewName("error/error");
return modelAndView;
}
}
异常处理器配置
在springmvc.xml中配置:
<!-- 配置全局异常处理器 -->
<bean class="com.aric.exception.ExceptionResolver"></bean>
RESTful支持
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数
Url格式:http://blog.dn.net/beat_the_world/article/details/45621673
拦截器
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
自定义拦截器
/**
* 登陆拦截器
*/
public class LoginInterceptor implements HandlerInterceptor{
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
/**
* controller执行后但未返回视图前调用此方法
* 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
/**
* controller执行前调用此方法
* 返回true表示继续放行,返回false拦截
* 这里可以加入登录校验、权限拦截等
*/
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object obj) throws Exception {
//1.登陆请求,放行
if (req.getRequestURI().contains("login")) {
return true;
}
//2.如果用户登陆,放行
if (req.getSession().getAttribute("user") != null) {
return true;
}
//3.否则,拦截
//跳转登陆页面登陆
req.getRequestDispatcher("/WEB-INF/jsps/login.jsp").forward(req, resp);
return false;
}
}
拦截器配置
在springmvc中配置
<!--配置局部拦截器-->
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1"/>
<ref bean="handlerInterceptor2"/>
</list>
</property>
</bean>
<bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
<bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>
<!-- 配置全局拦截器 -->
<mvc:interceptors>
<!-- 登陆拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.aric.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截器与过滤器的区别
过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围大;
拦截器Inerceptor依赖于框架容器,基于反射机制,只过滤请求.
未完待续.......