(六)Spring MVC常用注解(下)
6.2 参数绑定注解
6.2.1 @RequstParam注解
@RequstParam注解用于将制定的请求参数赋值给方法中的形参。@RequstParam注解可以使用的属性如表6-5所示。
表6-5 @RequstParam常用属性
属性名称 |
类 型 |
是否必填 |
描 述 |
name |
String |
否 |
指定请求头绑定的名称 |
value |
String |
否 |
name属性的别名 |
required |
Boolean |
否 |
指定参数是否必须绑定 |
defaultValue |
String |
否 |
请求没有传递参数而使用的默认值 |
@RequstParam注解的使用实例如下:
public class AyUserController {public String findById( String id){AyUser ayUser = ayUserService.findById(id);return "success";}}
public class AyUserController {public String findByNameAndPassword(String name,defaultValue = ) String password){System.out.println("name=" + name);System.out.println("password" + password);return "success";}}
当浏览器中输入URL请求:http://localhost:8080/user/findByNameAndPassword?name=ay时,name参数被赋值为ay,由于password没传任何值,故默认值为123。
6.2.2 @PathVariable注解
public class AyUserController {public String findPet( Long ownerId, Long petId) {// ...return "";}}
public class AyUserController {public String findPet( Long ownerId, Long petId) {// ...return "";}}
6.2.3 @RequestHeader注解
表6-6 @RequestHeader常用属性
属性名称 |
类 型 |
是否必填 |
描 述 |
name |
String |
否 |
指定请求头绑定的名称 |
value |
String |
否 |
name属性的别名 |
required |
Boolean |
否 |
指定参数是否必须绑定 |
defaultValue |
String |
否 |
请求没有传递参数而使用的默认值 |
一般请求头信息如下所示:
Host localhost:8080Accepttext/html,application/xhtml+xml,application/xml;q=0.9Accept-Languagefr,en-gb;q=0.7,en;q=0.3Accept-Encodinggzip,deflateAccept-CharsetISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive300
下面通过@RequestHeader注解获取Accept-Encoding和Keep-Alive信息,具体示例如下所示:
public class AyUserController {public String handle(String[] encoding,String[] accept) {//...return "";}}
6.2.4 @CookieValue注解
表6-7 @CookieValue 常用属性
属性名称 |
类 型 |
是否必填 |
描 述 |
name |
String |
否 |
指定请求头绑定的名称 |
value |
String |
否 |
name属性的别名 |
required |
Boolean |
否 |
指定参数是否必须绑定 |
defaultValue |
String |
否 |
请求没有传递参数而使用的默认值 |
public class AyUserController {public String handle( String cookie) {//...return "";}}
6.2.5 @ModelAttribute注解
public class AyUserController {public void init(){System.out.println("init ...");}public void init02(){System.out.println("init 02 ...");}public String findById( String id) {// ...return "";}public void init03(){System.out.println("init 03 ...");}}
init ...init 02 ...init 03 ...
@ModelAttribute注解有很多的额外使用方式,下面逐一进行介绍。
1. @ModelAtterbute方法无返回值的情况
(value = "/user")public class AyUserController {public void init(Model model){AyUser ayUser = new AyUser();ayUser.setId(1);ayUser.setName("ay");model.addAttribute("user", ayUser);}("/hello")public String hello(){return "hello";}}
<%@page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" isELIgnored="false"%><html><head><title>Getting Started: Serving Web Content</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>hello, ${user.name}</body></html>
2. @ModelAttribute标记方法有返回值
public class AyUserController {public String init( String name){return name;}public String hello(){return "hello";}}
model.addAttribute("name",name);对应前端src\main\webapp\WEB-INF\views\hello.jsp页面代码如下所示:<%@page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" isELIgnored="false"%><html><head><title>Getting Started: Serving Web Content</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>hello, ${name}</body></html>
3. @ModelAttribute注解和@RequestMapping注解
@ModelAttribute注解和@RequestMapping注解同时标记在一个方法上。
public class AyUserController {public String hello(){return "ay";}}
<%@page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" isELIgnored="false"%><html><head><title>Getting Started: Serving Web Content</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>hello, ${name}</body></html>
4. 使用@ModelAttribute注解方法的参数。
public class AyUserController {public AyUser init( Integer id,String name){AyUser ayUser = new AyUser();ayUser.setId(id);ayUser.setName(name);return ayUser;}public String hello( AyUser ayUser){return "hello";}
<%@page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" isELIgnored="false"%><html><head><title>Getting Started: Serving Web Content</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>hello, ${ayUser.name}</body></html>
6.2.6 @SessionAttribute和@SessionAttributes注解
表6-8 @RequestHeader常用属性
属性名称 |
类 型 |
是否必填 |
描 述 |
names |
String[] |
否 |
需要存储到session中数据的名称 |
value |
String |
否 |
name属性的别名 |
types |
Class<?>[] |
否 |
根据指定参数的类型,将模型中对应类型的参数存储到session中 |
下面看具体实例,具体代码如下:
public class AyUserController {public String redirectTest(Model model){AyUser ayUser = new AyUser();ayUser.setName("ay");model.addAttribute("ayUser",ayUser);return "redirect:hello";}public String hello(ModelMap modelMap){AyUser ayUser = (AyUser) modelMap.get("ayUser");System.out.println(ayUser.getName());return "hello";}}
public class AyUserController {public String redirectTest(Model model){AyUser ayUser = new AyUser();ayUser.setName("ay");model.addAttribute("ayUser",ayUser);return "redirect:hello";}public String hello( AyUser ayUser){System.out.println(ayUser.getName());return "hello";}}
("redirect")public String redirectTest(Model model,SessionStatus sessionStatus){AyUser ayUser = new AyUser();ayUser.setName("ay");model.addAttribute("ayUser",ayUser);//删除HttpSession中的属性sessionStatus.setComplete();return "redirect:hello";}
@SessionAttributes(types = {AyUser.class, AyRole.class},value = {"ayUser", "ayRole"})
type属性用来指定放入HttpSession当中的对象类型。
6.2.7 @ResponseBody和@RequestBody注解
1. @ResponseBody注解
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.5</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.5</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.5</version></dependency>
(1)返回普通的字符串
public class AyUserController {public String hello(){return "I am not view";}}
(2)返回集合对象
("/user")public class AyUserController {("/hello")public List<String> hello(){List<String> list = new ArrayList<String>();list.add("ay");list.add("al");return list;}}
public class AyUserController {public void hello( AyUser ayUser){System.out.println("name" + ayUser.getName());System.out.println("password" + ayUser.getPassword());}}
6.3 信息转换详解
6.3.1 HttpMessageConverter<T>
public interface HttpMessageConverter<T> {boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);List<MediaType> getSupportedMediaTypes();T read(Class<? extends T> clazz, HttpInputMessage inputMessage)throws IOException, HttpMessageNotReadableException;void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)throws IOException, HttpMessageNotWritableException;}
表6-9 HttpMessageConverter接口实现类
属性名称 |
描 述 |
StringHttpMessageConverter |
将请求信息转换为字符串,泛型T为String,可读取所有媒体类型(*/*),可通过supportedMediaTypes属性指定媒体类型。响应信息的媒体类型为text/plain(即Content-Type的值) |
(续表)
属性名称 |
描 述 |
ByteArrayHttpMessageConverter |
读写二进制数据,泛型T为byte[]类型,可读取*/*,可通过supportedMediaTypes属性指定媒体类型,响应信息媒体类型为application/octer-stream |
MarshallingHttpMessageConverter |
泛型T为Object,可读取text/xml和application/xml媒体类型请求,响应信息的媒体类型为text/xml或application/xml |
Jaxb2RootElementHttpMessageConverter |
通过JAXB2读写XML信息,将请求消息转换到标注XmlRootElement和XmlType注解的类中,泛型T为Object,可读取text/xml和application/xml媒体类型请求,响应信息的媒体类型为text/xml或application/xml |
MappingJacksonHttpMessageConverter |
利用jackson的ObjectMapper读写JSON数据,泛型T为Object,可读取application/json,响应媒体类型为application/json |
FormHttpMessageConverter |
表单与 MultiValueMap的相互转换。读支持响应MediaType为application/x-www-form-urlencoded,写支持的响应类型为application/x-www-form-urlencoded和multipart/form-data |
SourceHttpMessageConverter |
数据与javax.xml.transform.Source的相互转换。读支持响应MediaType为text/xml 和 application/xml,写支持的响应类型为text/xml 和 application/xml |
BufferedImageHttpMessageConverter |
数据与java.awt.image.BufferedImage的相互转换。读支持 MediaType为Java I/O API的所有类型,写支持的响应类型为Java I/O API的所有类型。 |
6.3.2 RequestMappingHandlerAdapter
RequestMappingHandlerMappingRequestMappingHandlerAdapterDefaultHandlerExceptionResolver
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapterimplements BeanFactoryAware, InitializingBean {//省略大量代码private List<HttpMessageConverter<?>> messageConverters;public RequestMappingHandlerAdapter() {StringHttpMessageConverter stringHttpMessageConverter= new StringHttpMessageConverter();stringHttpMessageConverter.setWriteAcceptCharset(false); // see SPR-7316this.messageConverters = new ArrayList<>(4);this.messageConverters.add(new ByteArrayHttpMessageConverter());this.messageConverters.add(stringHttpMessageConverter);this.messageConverters.add(new SourceHttpMessageConverter<>());this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());}}
l ByteArrayHttpMessageConverterl StringHttpMessageConverterl SourceHttpMessageConverterl AllEncompassingFormHttpMessageConverter
6.3.3 自定义HttpMessageConverter
<!-- 自定义RequestMappingHandlerAdapter --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/><bean class="org.springframework.http.converter.StringHttpMessageConverter"/><bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/></list></property></bean>
