Spring 从2.5版本之后,用户可以使用@Controller、@RequestMapping、@RequestParam、@ModelAttribute等类似这样的注释。
1.@Controller注解
使用@Controller注释的类不需要继承特定的父类或者实现特定的接口。
@Controller用于标记一个类,使用它标记的类就是一个Spring MVC Controller对象。Spring使用扫描机制查找应用程序中所有基于注解的控制器类。
分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解,而使用了@RequestMapping注解的方法才是真正处理请求的处理器
Spring处理步骤:
- 1.在Spring MVC的配置文件的头文件中引入spring-context
- 使用<context:compoent-scan/>元素,该元素的功能:启动扫描功能,以便注册带有@Controller、@Service、@Repository、@Compoent等注释的类成为Spring的Bean,base-package属性指定了需要扫描的类包。
@RequestMapping("/helloWorld")
public String helloWorld(Model model) {
model.addAttribute("message", "Hello World ya.");
return "HelloWorld";//这边的HelloWorld指的是JSP页面的名称
}
helloWorld方法接受一个Model类型参数。在该方法中添加一个字符串对象。然后该对象在返回的视图中通过request对象获取。
${requestScope.message}
Spring MVC其他用于参数绑定的注解
- 处理request body部分的注解
@RequestParam、@RequestBody
- 处理request uri部分的注释
@PathVariable
- 处理request header部分的注释
@RequestHeader 、@CookieValue
- 处理attribute类型的注释
@SessionAttributes、@ModelAttribute
2.@RequestMapping注释
@RequestMapping注释类型指示了Spring用哪一个类或者方法来处理请求动作,该注释可用于类或者方法
@Controller
@RequestMapping(value = "/test")
public class TestController {
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
}
当类上加上RequestMapping的时候,该类下面的所有方法的相关路径都要加上test。
2.1 RequestMapping注解支持的常用属性
- 1.value属性
value属性的作用就是将URL映射到方法上。如果在@RequestMapping中,只有一个属性,那么value可以省略。
- 2.method属性
该属性用来指示该方法仅仅处理哪些HTTP请求方式。如果没有指定,则可以处理任意的HTTP请求方式
- 3.consumes属性
该属性用来指定处理请求的提交内容类型(Content-Type)
@RequestMapping(value = "/hi", consumes = "application/json")
public String hi() {
return "hello";
}
表示方法处理request Content-Type为"application/json"类型的请求
- 4.produces属性
该属性指定返回的内容,必须是request请求头(Accept)中所包含的类型。
比如,请求的是application/json,那么返回的内容格式也必须是application/json
- 5.params属性
该属性指定request中必须包含某些参数值时,才让该方法处理。
@RequestMapping(value = "/hi", params = "myvalue=12")
public String hi() {
return "hello";
}
当请求的url包含myvalue参数时,并且该参数值为12,才开始处理请求。
- 6.header属性
该属性指定request中包含某些指定的header值,才让该方法处理请求
@RequestMapping(value = "/hi",headers = "referer=http://wwww.baidu.com")
public String hi() {
return "hello";
}
当请求request的header包含refer请求头和对应值为http://www.baidu.com的时候才处理请求
2.2请求处理方法可出现的参数类型
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model(org.springframework.ui.Model)
- ...
2.3请求处理方法可返回的类型
- ModelAndView
- Model(org.springframework.ui.Model)
- ...
2.4 Model和ModelView
- Model
Model接口存储模型数据,功能类似于java.util.Map接口
- ModelMap
ModelMap类实现了Map接口
@RequestMapping(value = "/hi")
public String hi(Model model, ModelMap modelMap) {
model.addAttribute("message", "Hello");
modelMap.addAttribute("message", "World");
String msg = "";
msg = model.asMap().get("message").toString() + modelMap.get("message").toString();
return "hello";
}
msg的结果为WorldWorld。因为Model的最终实现ExtendedModelMap,而ExtendedModelMap类是继承ModelMap。使用的都是同一个map对象
- ModelAndView
@RequestMapping(value = "/login")
public String login() {
return "login";
}
/**
* @ModelAttribute修饰的方法先于其他方法前调用,该方法用于接收前台JSP页面传入的参数
* @param name
* @param password
* @param mv
*/
@ModelAttribute
public void userModel(String name, String password, ModelAndView mv) {
User user = new User();
user.setName(name);
user.setPassword(password);
mv.addObject("user", user);
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView login(ModelAndView mv) {
User user=(User)mv.getModel().get("user");
return null;
}
3.参数绑定注解
3.1@RequestParam注解
该注解类型用于将指定的请求参数赋值给方法中的形参。
@RequestMapping("/register")
public String register(@RequestParam("name") String name, @RequestParam("password") String password) {
return null;
}
3.2 @PathVariable注解
该注解类型可以非常方便的获取请求URL中的动态参数。@PathVariable注解只支持一个属性value,类型为String,表示绑定的名称。如果省略,则默认绑定同名参数
@RequestMapping("/user/{userId}")
public String getUser(@PathVariable String userId){
return null;
}
3.3 @RequestHeader注解
该注解用于将请求的头信息映射到方法的形参上。
@RequestMapping("/header")
public String getHeaderParams(@RequestHeader(value = "Accept")String[] accepts){
return null;
}
3.4 @CookieValue注解
该注解用于将请求的Cookie数据映射到方法的形参上。
@RequestMapping("/cookie")
public void cookieTest(@CookieValue(value = "tcuser", defaultValue = "111") String sessionId) {
return;
}
JSESSIONID
3.5 @SessionAttributes注解
该注解允许我们有选择地指定Model中哪些属性需要转存到HttpSession中。只能用在类上,不能声明在方法上。
@Controller
@RequestMapping(value = "/test")
@SessionAttributes("user")
public class TestController {
@RequestMapping(value = "/login")
public String login() {
return "login";
}
/**
* @param name
* @param password
* @param mv
* @ModelAttribute修饰的方法先于其他方法前调用
*/
@ModelAttribute
public void userModel(String name, String password, Model mv) {
User user = new User();
user.setName(name);
user.setPassword(password);
mv.addAttribute("user", user);
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(Model mv) {
//User user = (User) mv.asMap().get("user");
return "welcome";
}
}
<%--
Created by IntelliJ IDEA.
User: stalkers
Date: 2017/7/29
Time: 下午9:04
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>welcome</title>
</head>
<body>
${requestScope.user.name}<br/>
${requestScope.user.password}
</body>
</html>
3.6 @ModelAttribute注解
该注释只支持一个属性value,类型为String。注意的是,使用该注释的方法会在Controller每个方法执行前被执行。因此在一个Controller映射到多个URL时,要谨慎使用。
@Controller
@RequestMapping("/attribute")
public class ModelAttributeController {
@ModelAttribute(value = "name")
public String user(String name){
String n= "2";
return n;
}
@RequestMapping("/login")
public String login(){
return "welcome";
}
}
${requestScope.name}
这边定义ModelAttribute的value为name,那么前台获取的方式
4.信息转换
4.1 HttpMessageConvert<T>接口
该接口负责将请求信息转换为一个对象(类型为T),并将对象绑定到请求方法的参数中或输出为响应参数。
DispatcherServlet默认装配了RequestMappingHandlerAdapter。即HttpMessageConvert由RequestMappingHandlerAdapter使用。
在springmvc-config加入
<!--自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdpter-->
<mvc:annotation-driven/>
这个是Spring MVC为@Controller分发请求所必须的。并且提供了数据绑定支持、@NumberFormatannotation支出、@DateTimeFormat支持、@Valid支持、读写XML的支持和读写Json的支持。
<!--使用默认的Servlet来响应静态文件-->
<mvc:default-servlet-handler/>
因为web.xml使用了DispatcherServlet截获所有请求url,而引入的script。DispatcherServlet会将"/"看成请求路径。找不到它的时候,会报404错误。当配置文件加上时候,Servlet找不到会去找静态的内容,即是js目录。
4.2 使用自定义的HttpMessageConvert接收Json格式的数据。
Spring默认使用Jackson处理json数据。如果使用其他开源类包处理,下面配置阿里巴巴的fastjson
<!--自定义配置JSON格式的数据-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;chartset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>