Springmvc架构
架构流程:
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
5、执行处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户
web.xml配置
强调一下配置springmvc前端控制器DispatcherServlet在Tomcat启动时候加载,如果不配置是在第一次请求才加载。如果配置10,其他的servlet没有配置,那也是优先级最高的。
<load-on-startup>标签:里面放的是正整数,不要使用1.因为1是tomcat中默认的Servlet的加载的级别. 正整数越小优先级越高.
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
注解
@RequestMapping注解**指定请求的url,其中“.action”可以加也可以不加。
@RequestMapping(value="/item")或@RequestMapping("/item)
value的值是数组,可以将多个url映射到同一个方法
@RequestMapping放在类名上边,设置请求前缀
@Controller
@RequestMapping("/item")
方法名上边设置请求映射url:
@RequestMapping放在方法名上边,如下:
@RequestMapping("/queryItem ")
请求方法限定
@RequestMapping(method = RequestMethod.GET)
如果通过Post访问则报错:
HTTP Status 405 - Request method 'POST' not supported
@RequestMapping(method = RequestMethod.POST)
GET和POST都可以
@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
@RequestParam :使用@RequestParam常用于处理简单类型的绑定。
value:参数名字,即入参的请求参数名字,如value=“item_id”表示请求的参数区中的名字为item_id的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报;
TTP Status 400 - Required Integer parameter 'XXXX' is not present
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,设置了默认值,即使required=true也可以不传item_id参数值
定义如下:
public String editItem(@RequestParam(value="item_id",required=true) String id) {
@RequestBody
@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口
将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。(也就是将请求json字符串转换成controller上的对象)
@ResponseBody
该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:
json,xml等,通过Response响应给客户端(将对象转成json字符串)
如:
前端页面请求js
//请求json响应json
function request_json(){
$.ajax({
type:"post",
url:"${pageContext.request.contextPath }/item/editItemSubmit_RequestJson.action",
contentType:"application/json;charset=utf-8",
data:'{"name":"测试商品","price":99.9}',
success:function(data){
alert(data);
}
});
}
后台controller
// 商品修改提交json信息,响应json信息
@RequestMapping("/editItemSubmit_RequestJson")
public @ResponseBody Items editItemSubmit_RequestJson(@RequestBody Items items) throws Exception {
System.out.println(items);
//itemService.saveItem(items);
return items;
}
参数绑定
绑定简单类型:
当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。
支持的数据类型
参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
整形:Integer、int
字符串:String
单精度:Float、float
双精度:Double、double
布尔型:Boolean、boolean
说明:对于布尔类型的参数,请求的参数值为true或false。
自定义参数绑定:
由于日期数据有很多种格式,所以springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。
自定义Converter:
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
配置Converter:
<!-- 加载注解驱动 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 转换器配置 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.itcast.springmvc.convert.DateConverter"/>
</set>
</property>
</bean>
ModelAndView
ModelAndView对象中,将视图设置为“/WEB-INF/jsp/itemList.jsp”
ModelAndView modelAndView = new ModelAndView();
//添加model
modelAndView.addObject("itemList", itemList);
//添加视图
modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
//modelAndView.setViewName("itemsList");
return modelAndView;
Model/ModelMap
使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap。
如果使用Model则可以不使用ModelAndView对象,Model对象可以向页面传递数据,View对象则可以使用
String返回值替代。不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。
public String itemEdit(HttpServletRequest request, Model model) {
model.addAttribute("item", items);
return "editItem";
controller方法
在controller方法形参上可以定义request和response,使用request或response指定响应结果:
1、使用request转向页面,如下:
request.getRequestDispatcher("页面路径").forward(request, response);
2、也可以通过response页面重定向:
response.sendRedirect("url")
3、也可以通过response指定响应结果,例如响应json数据如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
Redirect重定向
Contrller方法返回结果重定向到一个url地址
//重定向到queryItem.action地址,request无法带过去
return "redirect:queryItem.action";
redirect方式相当于“response.sendRedirect()”,转发后浏览器的地址栏变为转发后的地址,因为转发即执
行了一个新的request和response。
由于新发起一个request原来的参数在转发时就不能传递到下一个url,如果要传参数可
以/item/queryItem.action后边加参数,如下:
/item/queryItem?...&…..
forward转发
controller方法执行后继续执行另一个controller方法
//结果转发到editItem.action,request可以带过去
return "forward:editItem.action";
forward方式相当于“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还
是原来的地址。转发并没有执行新的request和response,而是和转发前的请求共用一个request和
response。所以转发前请求的参数在转发后仍然可以读取到。
controller组件扫描器
使用组件扫描器省去在spring容器配置每个controller类的繁琐。使用<context:component-scan>自动扫描
标记@controller的控制器类,配置如下:
<!-- 扫描controller注解,多个包中间使用半角逗号分隔 -->
<context:component-scan base-package="cn.itcast.springmvc.controller.first"/>
解决post、get乱码问题:
解决post乱码问题:
在web.xml中加入:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
对于get请求中文参数出现乱码解决方法有两个:
修改tomcat配置文件添加编码与工程编码一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
另外一种方法对参数进行重新编码:
String userName new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码
springmvc与struts2不同
1、springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
2、springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多
例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
3、Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request
请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中
的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
RESTful支持
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠
释。
资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数
Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、
查询。一般使用时还是post和get。Put和Delete几乎不使用。
配置:
添加DispatcherServlet的rest配置。
<servlet>
<servlet-name>springmvc-servlet-rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-servlet-rest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
URL 模板模式映射
@RequestMapping(value="/ viewItems/{id}"):{×××}占位符,请求的URL可以
是“/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。
@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。
如
@RequestMapping("/viewItems/{id}")
public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{
//方法中使用@PathVariable获取userid的值,使用model传回页面
//调用 service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(id);
return itemsCustom;
}
如果RequestMapping中表示为"/viewItems/{id}",id和形参名称一致,@PathVariable不用指定名称。
静态资源访问mvc:resources
如果在DispatcherServlet中设置url-pattern为 /则必须对静态资源进行访问处理。
spring mvc 的<mvc:resources mapping="" location="">实现对静态资源进行映射访问。
如下是对js文件访问配置:
(该文件夹位于webapp下js文件夹,这样配置可以直接访问到静态资源不进行拦截)
<mvc:resources location="/js/" mapping="/js/**"/>
springmvc图片上传,Tomcat配置虚拟目录
图片上传详细见项目及文档。
Tomcat配置虚拟目录:
在tomcat上配置图片虚拟目录,在tomcat下conf/server.xml中添加:
<Context docBase="F:\develop\upload\temp" path="/pic" reloadable="false"/>
访问http://localhost:8080/pic即可访问F:\develop\upload\temp下的图片。
也可以通过eclipse配置:
异常处理器
系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:
详细见项目。
拦截器
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
配置2个同样的拦截器都放行结果:
配置2个同样的拦截器,拦截器1不放行结果:
配置2个同样的拦截器,拦截器1放行,2不放行
详细见示例项目。