序言
1.Spring MVC概述:
Spring MVC是Spring提供的一个强大而灵活的web框架。借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单。这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中。
Spring MVC主要由DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图组成。他的两个核心是两个核心:
处理器映射:选择使用哪个控制器来处理请求
视图解析器:选择结果应该如何渲染
通过以上两点,Spring MVC保证了如何选择控制处理请求和如何选择视图展现输出之间的松耦合。
2.SpringMVC运行原理
(1) Http请求:客户端请求提交到DispatcherServlet。
(2) 寻找处理器:由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。
(3) 调用处理器:DispatcherServlet将请求提交到Controller。
(4)(5)调用业务处理和返回结果:Controller调用业务逻辑处理后,返回ModelAndView。
(6)(7)处理视图映射并返回模型: DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
(8) Http响应:视图负责将结果显示到客户端。
3.SpringMVC接口解释
(1)DispatcherServlet接口:
Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。
(2)HandlerMapping接口:
能够完成客户请求到Controller映射。
(3)Controller接口:
需要为并发用户处理上述请求,因此实现Controller接口时,必须保证线程安全并且可重用。
Controller将处理用户请求,这和Struts Action扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。
从宏观角度考虑,DispatcherServlet是整个Web应用的控制器;从微观考虑,Controller是单个Http请求处理过程中的控制器,而ModelAndView是Http请求过程中返回的模型(Model)和视图(View)。
(4)ViewResolver接口:
Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,从而将相应结果渲染给客户。
4.DispatcherServlet:
是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分。其主要工作有以下三项:
(1)截获符合特定格式的URL请求。
(2)初始化DispatcherServlet上下文对应WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联。
(3)初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。
一、 Spring MVC Annotation
Spring2.5引入注解式处理器支持,通过@Controller和@RequestMapping注解定义我们的处理器类。并且提供了一组强大的注解:
需要通过处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter来开启支持@Controller和@RequestMapping注解的处理器。
@Controller:用于标识是处理器类;
@RequestMapping:请求到处理器功能方法的映射规则;
value="/simple/revisited":请求url,没有其他属性可以不声明value=。
method=RequestMethod.GET,:指定请求方式。
headers="Accept=text/plain"
@PostMapping
@GetMapping
@RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定;
@ModelAttribute:请求参数到命令对象的绑定;
@SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中;
@InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;
Spring3.0引入RESTful架构风格支持(通过@PathVariable注解和一些其他特性支持),且又引入了更多的注解支持:
@CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定;
@RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定;
@RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换);
@ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);
@ResponseStatus:定义处理器功能处理方法/异常处理器返回的状态码和原因;
@ExceptionHandler:注解式声明异常处理器;
@PathVariable:请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI;
Spring mvc4.x 注解概述
http://www.cnblogs.com/davidwang456/p/4432410.html
还有比如:
JSR-303验证框架的无缝支持(通过@Valid注解定义验证元数据);
使用Spring 3开始的ConversionService进行类型转换(PropertyEditor依然有效),支持使用@NumberFormat和@DateTimeFormat来进行数字和日期的格式化;
HttpMessageConverter(Http输入/输出转换器,比如JSON、XML等的数据输出转换器);
二、 Mapping Requests
@RequestMapping
value="/mapping/path/*" *:代表任意字符串
params="foo" 代表请求必须带名为foo的参数。
params="!foo" 代表请求必须不带名为foo的参数。
headers="FooHeader=foo" 请求中必须包含名字为FooHeader,值为foo的请求头
headers="!FooHeader" 请求中不包含名字为FooHeader的请求头
consumes=MediaType.APPLICATION_JSON_VALUE 设置请求接收的数据类型为JSON。配合@RequestBody把json转换为参数列表中的Bean对象。
produces=MediaType.APPLICATION_JSON_VALUE 设置响应的数据格式为JSON。配合@ResponseBody把返回类型Bean转换为JSON。
数据传输格式:xml和json
FastJSON、Gson和Jackson性能对比
http://blog.youkuaiyun.com/accountwcx/article/details/50252657
SpringMVC返回json数据的三种方式
http://blog.youkuaiyun.com/shan9liang/article/details/42181345
1、请求后台返回JSON数据实现步骤:
请求方式:
A. 设置请求头Accept=application/json
B. url后带.json后缀,默认可以省略。
1. 导入Jackson支持库
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
2. 修改mvc配置文件src\main\webapp\WEB-INF\springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描web层的@Controller-->
<context:component-scan base-package="com.springmvc.demo.web"/>
<mvc:annotation-driven/>
</beans>
3. 编写控制层返回json代码
@RequestMapping(value="/mapping/user", method=RequestMethod.GET)
public @ResponseBody User byProducesJson() {
return new User();
}
4. 测试:
http://localhost:8081/springmvc/mapping/user
http://localhost:8081/springmvc/mapping/user.json
2、请求后台返回XML数据实现步骤:
请求方式:
A. 设置请求头Accept=application/xml
B. url后带.xml后缀,默认可以省略。
1. 在返回JavaBean类声明之前加上@XmlRootElement
@XmlRootElement
public class User{}
默认返回均为xml,如果想返回json的时候必须带上.json后缀即可。
2. 编写控制层返回json代码
@RequestMapping(value="/mapping/user", method=RequestMethod.GET)
public @ResponseBody User byProducesJson() {
return new User();
}
3. 测试:
http://localhost:8081/springmvc/mapping/user 默认:xml
http://localhost:8081/springmvc/mapping/user.json 返回:json
三、 Obtaining Request Data
1、参数列表接收请求参数
@RequestParam String foo
@RequestParam(name="foo",required=true,defaultValue="guest") String foo
Name:指定接收参数的名字
Required:是否必须提交属性
defaultValue:设置不传值时的默认值
2、请求参数封装到JavaBean
1. 提交属性字段与JavaBean字段一致
2. JavaBean必须为接收字段提供对应Setter函数。
3、从请求Url中获取数据
@RequestMapping(value=" path/{var}")
public @ResponseBody String withPathVariable(@PathVariable Stringvar) {}
4、从url解析矩阵变量
a) 启用矩阵变量配置
<mvc:annotation-driven enable-matrix-variables="true"/>
b) 请求url带matrixvars;关键字
例如:matrixvars;foo=bar/simple
@RequestMapping(value="{path}/simple", method=RequestMethod.GET)
public @ResponseBody String withMatrixVariable(@PathVariable Stringpath,@MatrixVariable Stringfoo) {
return "Obtained matrix variable 'foo=" +foo +"' from path segment '" +path +"'";
}
5、从servlet不同作用域获取参数
@RequestHeader String Accept :获取请求Accept的值
@CookieValue String openid_provider :获取Cookie 的值,openid_provider必须要 存在于浏览器的Cookie中
@RequestBody String body
HttpEntity<String> entity
四、 Generating Responses
springmvc @Controller中的方法,如果返回类型为String。
Ø 那么带@ResponseBody,则返回字符串内容。
Ø 如果不带@ResponseBody,则进行页面跳转。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
Ø 修改web.xml把DispatcherServlet的拦截/*修改为/
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Ø 例如:访问/login地址则自动重定向到/WEB-INF/views/login.jsp
@RequestMapping("/login")
public Stringlogin() {
return "login";
}
设置响应内容编码为UTF-8:@ResponseBody String
Ø 请求的时候设置请求响应编码:req.setRequestHeader("Accept","text/plain;charset=UTF-8");
Ø 设置请求映射响应编码:@RequestMapping(value="/charset/produce", produces="text/plain;charset=UTF-8")
Ø 全局设置:修改Spring mvc配置文件springmvc-servlet.xml,在mvc:annotation-driven配置中添加StringHttpMessageConverter。
<mvc:annotation-driven enable-matrix-variables="true">
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Ø 响应状态编码:https://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81/5053660?fr=aladdin
@RequestMapping("/entity/headers")
public ResponseEntity<String> responseEntityCustomHeaders() {
HttpHeaders headers =new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity<String>("Msg",headers, HttpStatus.OK);
}
五、 Message Converters
接收和响应String、form、json、xml、atom、rss消息数据转换。
@ModelAttribute
@RequestBody
@ResponseBody
@XmlRootElement
需要实现Atom+RSS需要引人:
<!-- Rome Atom+RSS -->
<dependency>
<groupId>com.rometools</groupId>
<artifactId>rome</artifactId>
<version>1.5.0</version>
</dependency>
六、 Rendering Views
<!-- 设置主页面:访问/自动跳转到home视图 -->
<mvc:view-controller path="/" view-name="index"/>
<!-- springmvc 页面重定向设置: -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
/WEB-INF/views/index.jsp
springMVC 几种页面跳转方式:
http://blog.youkuaiyun.com/jsu_9207/article/details/51281027
七、 Type Conversion
1. 自动数据类型转换
a) String自动转换为其他8种封装类型
2. 日期格式转换
1. 导入joda-time的依赖
<!-- Joda Time Library -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>
2. String转换为java.util.Date使用@DateTimeFormat
@DateTimeFormat(iso=ISO.DATE_TIME)
@DateTimeFormat(iso=ISO.DATE)
@DateTimeFormat(iso=ISO.TIME)
@DateTimeFormat(pattern ="yyyy/MM/dd HH:mm:ss")
注意:
响应日期格式:2010/07/04(推荐)
2010-07-04(不推荐)->NaN-NaN-NaN
少8小时,设置日期为东8区。
解决:返回字段的getter方法上声明:
@JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss",timezone = "GMT+8")
3. 转换为集合、Map格式
4. 自定义格式化注解(接收固定格式的数据并且移除特殊符号)
a) 声明注解类MaskFormat
b) 声明MaskFormatAnnotationFormatterFactory必须实现AnnotationFormatterFactory
c) 把自定义的AnnotationFormatterFactory配置到spring mvc配置文件中
<beans:bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<beans:property name="formatters">
<beans:bean class="com.demo.convert.annotation.MaskFormatAnnotationFormatterFactory"/>
</beans:property>
</beans:bean>
八、 Validation
<!-- JSR 303 with Hibernate Validator -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
1. 在Entity中声明hibernate-validator校验注解
@NotNull
@Max(5)
@NotNull
@Future
//…
2. 接收数据时使用@Valid启用校验
@RequestMapping("/validate")
public @ResponseBody String validate(@Valid JavaBeanbean, BindingResultresult) {
if (result.hasErrors()) {
return "Object has validation errors";
} else {
return "No errors";
}
}
九、 File Upload
1.导入commons-fileupload和commons-io支持
<!-- File Upload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0.1</version>
</dependency>
2.修改springmvc配置文件,增加上传配置(扩展设置上传限制,例如文件大小)
<!-- Only needed because we require fileupload in the org.springframework.samples.mvc.fileupload package -->
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
3.修后台接收上传文件(多文件上传)
@RequestMapping(method=RequestMethod.POST)
public void processUpload(@RequestParam MultipartFile file, Model model)throws IOException {
model.addAttribute("message","File '" +file.getOriginalFilename() +"' uploaded successfully");
}
4.前端设置提交的表单类型enctype="multipart/form-data"
<form id="fileuploadForm" action="${actionUrl}" method="POST" enctype="multipart/form-data" class="cleanform">
<label for="file">File</label>
<input id="file" type="file" name="file" />
<p><button type="submit">Upload</button></p>
</form>
十、 Spring MVC + Servlet API
public @ResponseBody String byPathPattern(HttpServletRequest request) {}
public @ResponseBody String response(HttpServletResponse response) {}
public @ResponseBody String session(HttpSession session) {}
public @ResponseBody String write(Writer responseWriter) {}
public @ResponseBody String read(Reader requestBodyReader) {}
public @ResponseBody String output(OutputStream os) {}
public @ResponseBody String input(InputStream is) {}
十一、 解决Spring MVC中文乱码问题
1. 运行环境的编码设置:
a) 服务器编码:tomcat/jetty/websphere..
例如:maven插件
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8081</port>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
Tomcat目录:apache-tomcat\conf\server.xml
<Connector URIEcoding="UTF-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<Connector URIEcoding="UTF-8" port="8009" protocol="AJP/1.3" redirectPort="8443"/>
b) 数据库编码设置
Ø 创建数据库选中UTF-8编码
Ø 连接数据库设置URL:jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=UTF-8
c) IDE工具工作区间编码设置
Preferences->General->Workspace->Test file encoding->UTF-8
2. Jsp编码设置:
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Index Page</title>
</head>
<body></body>
</html>
3. 修改项目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>
4. 响应JSON编码设置(可选)
response.setContentType("application/json;charset=UTF-8");
5. 接收请求数据为乱码:
a) request.setCharacterEncoding("UTF-8");
b) String str = new String((request.getParameter("bigQuestionTypeName")).getBytes("iso-8859-1"),"utf-8");
可以打印当前编码:System.out.println(request.getCharacterEncoding());
6. Spring mvc设置全局响应编码(配合@ResponseBody使用):
<mvc:annotation-driven enable-matrix-variables="true">
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
十二、 Spring MVC静态资源访问
在SpringMVC中常用的就是Controller与View。但是我们常常会需要访问静态资源,如html、js、css、image等。默认的访问的URL都会被DispatcherServlet所拦截,所以jsp或者html中则无法访问静态资源文件(js、css、image)。
解决方案1:直接在spring mvc配置文件中spirngmvc-servlet.xml中添加资源映射。
<mvc:resourcesmapping="/resources/**" location="/resources/" />
<mvc:resourcesmapping="/images/**" location="/images/" />
<mvc:resourcesmapping="/js/**" location="/js/" />
mapping:映射
location:本地资源路径,注意必须是webapp根目录下的路径。
两个*,它表示映射resources/下所有的URL,包括子路径(即接多个/)
WEB-INF目录作用
WEB-INF是Java的WEB应用的安全目录。所谓安全就是客户端无法直接访问,只有服务端可以访问的目录。如果想在页面中直接访问其中的文件,必须通过web.xml文件对要访问的文件进行相应映射才能访问。
当然,你非要放在WEB-INF中,则必须修改resources映射,如:
<resourcesmapping="/js/**" location="/WEB-INF/js/" />
解决方案2:
<mvc:default-servlet-handler/>
会把 "/**" url,注册到SimpleUrlHandlerMapping的urlMap中,把对静态资源的访问由HandlerMapping转到org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler处理并返回.
DefaultServletHttpRequestHandler 使用就是各个 Servlet容器自己的默认Servlet.
SpringMVC访问静态资源的三种方式
http://www.cnblogs.com/caoyc/p/5639078.html