SpringMVC 配置文件可以放在 WEB-INF 下

  • 命名规范:[servlet-name]-servlet.xml
  • 位置:/WEB-INF 目录下 ,示例:/WEB-INF/springDispatcherServlet-servlet.xml
  • 使用默认配置文件可以省略init-param
1
2
3
4
5
6
7
8
9
10
11
12
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

@RequestMapping 注解的其他映射方式

1、根据请求参数情况映射

请求参数中必须包含 userName @RequestMapping(params=”userName”)

请求参数中不能包含 userName @RequestMapping(params=”!userName”)

请求参数中必须包含 userName 且值必须为 Tom @RequestMapping(params=”userName=Tom”)

请求参数中必须包含 userName 但值不能为 Tom @RequestMapping(params=”userName=!Tom”)

请求参数中必须包含 userName 且值为 Tom,同时必须包含 userPwd 但值不限 @RequestMapping(params={“userName=Tom”,”userPwd”} )

2、根据请求消息头内容映射

根据Accept-Language:zh-CN,zh;q=0.8映射

@RequestMapping (value=”headers_request”,headers= “Accept-Language=zh-CN,en;q=0.8” )

3、使用 Ant 风格通配符

?:匹配文件名中的一个字符

*匹配文件名中的任意字符

: 匹配多层路径

@RequestHeader

帮我们获取请求消息头数据

1
2
3
4
5
@RequestMapping("/getRequestHearder")
public String getRequestHeader(@RequestHeader(value="User-Agent",defaultValue="miss") String userAgent) {
System.out.println(userAgent);
return "result";
}

@CookieValue

帮我们获取 Cookie 值

1
2
3
4
5
@RequestMapping("/getCookie")
public String getCookie(@CookieValue(value="JSESSIONID", defaultValue="miss") String jSessionId) {
System.out.println(jSessionId);
return "result";
}

@ModelAttribute

标注了@ModelAttribute的方法会在当前 handler 类中每一个 handler 方法执行前执行。

@SessionAttribute

1、只能标注在类上

1
2
3
4
@Controller
@SessionAttributes(value="user")
public class SessionHandler {
……

2、value 属性

根据 value 属性中指定的值从请求域中读取一个对象,然后保存到 Session 域中。

3、type 属性

@SessionAttributes(types=User.class) 从请求域中读取一个类型为 User 的对象保存到 Session 域中。

4、存在的问题

使用@SessionAttributes 注解会在下述情况中引发异常

情景描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
@SessionAttributes(value="user")
public class SessionHandler {

@RequestMapping("/login")
public String login(HttpSession session, User user) {

//验证User是否可以登录
//……

//如果可以
session.setAttribute("loginUser", user);

return "success";
}
}

handler 方法的入参的类型是 User,类名首字母小写后正好是@SessionAttributes 注解中指定的 value 属性值。

行为描述

@SessionAttributes 注解会在执行 handler 方法前从 Session 域中获取 User 对象,然后将请求参数注入到这个 User 对象中。然后传入 handler 方法。

此时如果 Session 域中找不到 User 对象,那么就会抛出如下异常:

org.springframework.web.HttpSessionRequiredException: Session attribute ‘user’ required - not found in session

解决办法

1
2
3
4
@ModelAttribute
public User getUser() {
return new User();
}

标注了@ModelAttribute 注解的方法,会让@SessionAttributes 注解可以从模型中获取 User 对象来接收请求参数。

当 PUT 和 DELETE 请求遇到 Tomcat8

Restful 风格(Delete 请求和 PUT 请求)在高版本 Tomcat 中无法转发到 JSP 页面,解决办法是在 JSP 页面上设置:isErrorPage="true"

HttpEntity

通过 HttpEntity 对象可以获取请求相关信息

1
2
3
4
5
6
7
@RequestMapping(value="/testHttpEntity")
public ModelAndView fun1(HttpEntity<String> entity) {
System.out.println("entity->>" +entity);
System.out.println("body--->>>" + entity.getBody());
System.out.println("header--->>>" + entity.getHeaders());
return new ModelAndView("redirect:/jsp/index.jsp");
}

ResponseEntity

通过 ResponseEntity 对象可以设置响应相关信息,下面的例子借助 ResponseEntity 实现了文件下载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@RequestMapping(value="/download")
public ResponseEntity<byte[]> download(HttpSession session) {
// 读取下载文件获取输入流
InputStream is = session.getServletContext().getResourceAsStream("/imgs/ludashi.jpg");
try {
// 读取文件
int len = is.available();
byte[] buffer = new byte[len];
is.read(buffer);
// 创建响应头
MultiValueMap map = new HttpHeaders();
// 告诉客户端返回的数据以附件的形式处理
map.add("Content-Disposition", "attachment; filename=a.jpg");
// 创建ResponseEntity 设置返回结果。
// HttpStatus.OK 表示状态码 200
// 创建响应头
ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(buffer, map, HttpStatus.OK);

return entity;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关流
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}

HttpMes2sageConverter

HttpMessageConverter是一个策略接口。是 SpringMVC 专门提供的做消息转换的工具接口。

接口说明如下:

Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.

简单说就是 HTTP request (请求)和 response (响应)的转换器。

该接口有 5 个方法:获取支持的 MediaType(application/json 之类),接收到请求时判断是否能读(canRead),能读则读(read);返回结果时判断是否能写(canWrite),能写则写(write)。

请求的报文(请求的 HTTP 协议内容)会被封装成为 HttpInputMessage 实现类。然后交给 HttpMessageConverter 类去转换。 然后,我们 SpringMVC 程序的返回数据,交给 HttpMessageConverter 转换成为 HttpOutputMessage 实现类,最终输出成为响应报文(响应的 Http 协议)

而 springMVC 为我们提供了 9 个自带的消息转换器