6、Spring MVC 之 定义@RequestMapping处理方法
2016-07-29 23:53
453 查看
@RequestMapping处理器方法可以非常灵活的签名。支持的方法参数和返回值在以下部分中描述。大多数参数可用于任意顺序除了BindingResult这个唯一的参数例外。下一节中将会描述。
note:Spring 3.1引入了一套新的@RequestMapping方法的支持类.分别是RequestMappingHandlerMapping和RequestMappingHandlerAdapter。它们被推荐使用,甚至你在使用Spring MVC的新特性时必须使用它们。在MVC命名空间与MVC的Java配置这些新的支持类是默认启用的。如果不使用新特性必须明确的配置。
1. Servlet API中的Request或者Response对象。选择一些特殊的request或者response类型。例如:
2. Servlet API中的Session对象:
note : 在Servlet环境中使用session对象可能不会线程安全。如果多个request被允许使用同一个session可以考虑把RequestMappingHandlerAdapter的synchronizeOnSession属性设置为true。
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19. Command或者form对象来绑定请求参数到bean(通过setters)或者通过字段。通过
20.
21.
22.
注意:
BindingResult与@ModelAttribute的顺序不正确.
注意
如果在
1. A
2. A
3. A
4. A
5. A
6.
7. 如果方法使用
8. An
9. An
10. A
11. A
12. A
13. A
14. An
15. A
16. Any other return type,被认为是做为是暴露的view中的model属性。可以在方法级别使用
下面的代码片段展现它的用法:
如果方法中参数使用了这个@RequestParam,那么request中必须有对应的参数.当然你也可以通过设置@RequestParam的
当
你使用一种
1.
2.
3.
4.
如果你想使用Spring MVC中更多的信息转换,可以使用Spring MVC中的namespace与Spring MVC的Java config来进行注册。如果你打算读/写XML,你需要配置
当你在方法参数上使用
与注解了
上面的例子将会导致
在上面的例子中,获取request header中
与
当
注意
在一个Controller中可以有许多个
鉴于上面的例子可以Pet实例从何而来?有下面几种可能:
1. 由于
2. 在同一个Controller中由于使用了
3. 它可能已经在URI模板变量或者type转换中获取到了.
4. 它可以已经使用它的默认constructor初始化好了。
一个
在这个例子中,model属性的名称(“account”)与URI模板变量的名称相匹配.如果你注册
下一步就是数据绑定,
当进行数据绑定的时候可能会有一些错误,比如说:缺少必须的fields或者类型转换errors。你如果需要check这个errors,可以再
在上面的例子中,你可以使用
或者你可以自动调用验证通过添加JSR-303中的
下面的代码片段展示了这个注解的用法,并且指明了model属性的名称:
为了支持HTTP的PUT请求或者PATCH请求,
上面的filter会拦截HTTP中的PUT与PATCH请求通过在content的类型为
注意:因为
下面的例子是如何获取
如果方法参数不是String类型,Spring会自动进行类型转换.具体可以看”Method Parameters And Type Conversion”.这个标签支持Servlet与Portlet环境下的handler方法.
下面是一个简单的request的header:
下面的代码就是简单的展示如何获取headers中
如果方法参数不是
注意:Spring MVC内嵌的支持以逗号分隔的String转换成String类型的array/collection或者其它转换系统能够识别的类型.这个标签支持Servlet与Portlet环境下的handler方法.
init-binder方法支持所有的
下面就是一个简单的例子用来表示
在Spring4.2中,一般考虑使用
下面的例子是来自于PetClinic应用,展示了使用自定义的
一个类如果被
Check out the @ControllerAdvice documentation for more details.
在controller的方法中使用
注意:
Controller依赖视图解析,只需序列化视图类添加然后添加到模型:
controllers依赖view解析,当request的请求参数中有一个叫做
note:Spring 3.1引入了一套新的@RequestMapping方法的支持类.分别是RequestMappingHandlerMapping和RequestMappingHandlerAdapter。它们被推荐使用,甚至你在使用Spring MVC的新特性时必须使用它们。在MVC命名空间与MVC的Java配置这些新的支持类是默认启用的。如果不使用新特性必须明确的配置。
1、支持的方法参数类型
下面是是支持的方法参数:1. Servlet API中的Request或者Response对象。选择一些特殊的request或者response类型。例如:
ServletRequest或者
HttpServletRequest。
2. Servlet API中的Session对象:
HttpSession对象。论证这种类型的执行存在相应的会话。因此,这个参数永远不会为
Null。
note : 在Servlet环境中使用session对象可能不会线程安全。如果多个request被允许使用同一个session可以考虑把RequestMappingHandlerAdapter的synchronizeOnSession属性设置为true。
3.
org.springframework.web.context.request.WebRequest或者
org.springframework.web.context.request.NativeWebRequest.如果没有依赖本地Servlet / Portlet API,允许使用通用请求参数访问request/session属性。
4.
java.util.Locale.当前请求的locale。在Spring MVC中可以通过配置
LocaleResolver/
LocaleContextResolver,来决定使用可用的具体的语言环境解析器。
5.
java.util.TimeZone(Java 6+) /
java.time.ZoneId(on Java 8): 与当前请求相关联的时区,通过
LocaleContextResolver来决定。
6.
java.io.InputStream/
java.io.Reader.访问request的内容.这个值是Servlet API暴露的原始的InputStream /Reader.
7.
java.io.OutputStream/
java.io.Writer.生成reponse的内容.这个值是Servlet API暴露的原始的OutputStream/Writer.
8.
org.springframework.http.HttpMethod.HTTP请求的方法。
9.
java.security.Principal.包含当前身份验证的用户。
10.
@PathVariable.被注释的参数用于获取URI模板变量。
11.
@MatrixVariable.注解的参数访问位于URI路径段名称-值对。
12.
@RequestParam.注解的参数访问特定的Servlet请求参数。参数值转换为声明的方法参数类型。
13.
@RequestHeader.注解的参数访问Servlet的HTTP请求中特殊的headers。参数值转换为声明的方法参数类型。
14.
@RequestBody.注解的参数访问HTTP请求的body.参数值使用HttpMessageConverters转换为声明的方法参数类型。
15.
@RequestPart.注解的参数获取的content中的”multipart/form-data”要求的部分。主要用于Spring MVC支持文件上传。
16.
HttpEntity. 用于访问Servlet中的HTTP请求headers与content中的属性.request流将使用HttpMessageConverters被转换成entity的body.
17.
java.util.Map/
org.springframework.ui.Model/
org.springframework.ui.ModelMap.装饰web视图暴露的的隐式模型.
18.
org.springframework.web.servlet.mvc.support.RedirectAttributes.指定的精确的属性用于如果发生重定向并添加flash属性。(把属性临时的储存在服务端,当进行重定向的时候,可以从request里面获取它)
19. Command或者form对象来绑定请求参数到bean(通过setters)或者通过字段。通过
@InitBinder注解方法或者HandlerAdapter配置,我们也可以自定义类型转换。可以参考
RequestMappingHandlerAdapter的
webBindingInitializer这个属性。这样的命令对象及其验证结果将会默认以model的属性暴露.使用command类的类名 – 例如.一个command对象的的类型为”some.package.OrderAddress”对应的model属性就是”orderAddress”.
@ModelAttribute注释可用于自定义一个方法参数模型属性名称使用。
20.
org.springframework.validation.Errors/
org.springframework.validation.BindingResult.前命令之前或表单对象验证结果.(方法参数的前面)
21.
org.springframework.web.bind.support.SessionStatus.状态处理用于将表单处理标记为完成.如果在处理类(Controller)上面声明
@SessionAttributes这个注解,就会引用清除session属性。
22.
org.springframework.web.util.UriComponentsBuilder.一个builder用于准备一个URL相对于当前请求的host,port,scheme,context path和servlet映射的文字部分。
注意:
Errors或者
BindingResult必须作为Model对象的参数。Model对象是与方法绑定在一起的。Spring MVC会给写个Model创建一个单独的
BindingResult的对象。下面这个例子是错误的,不会运行:
BindingResult与@ModelAttribute的顺序不正确.
@RequestMapping(method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pet") Pet pet, Model model, BindingResult result) { ... }
注意
如果在
Pet与
BindingResult中有
Model对象。如果你想这段逻辑工作,需要把这些参数像下面进行重新排序。
@RequestMapping(method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, Model model) { ... }
2、方法支持的返回值类型
下面的是方法支持的返回值类型:1. A
ModelAndViewobject,这个model隐含command对象和
@ModelAttribute注释的结果.
2. A
Modelobject,返回一个Model对象来表示模型,而视图名则利用
RequestToViewNameTranslator把请求转换为视图名称。这个model隐含command对象和
@ModelAttribute注释的结果.
3. A
Mapobject,返回一个Map对象来表示模型,而视图名则利用
RequestToViewNameTranslator把请求转换为视图名称。这个model隐含command对象和
@ModelAttribute注释的结果.
4. A
Viewobject,这个model隐含command对象和
@ModelAttribute注释的结果.处理方法通过声明的
Model类型的参数来编程填充这个模型。
5. A
Stringvalue,这个String值被Spring MVC解读为合理的页面name.这个model隐含command对象和
@ModelAttribute注释的结果.处理方法通过声明的
Model类型的参数来编程填充这个模型。
6.
void,返回空void表示方法自己处理响应,一种办法是:通过声明一个
ServletResponse或
HttpServletResponse类型的参数来直接输出响应内容,第二种是:通过
RequestToViewNameTranslator把请求转化为视图名,此方法不用在处理方法中声明一个response参数,不过这种方法是能在Servlet环境下使用。
7. 如果方法使用
@ResponseBody,返回值将会被写入到response的HTTP的body中。将通过HttpMessageConverters把返回值转换为声明方法参数类型.
8. An
HttpEntity<?>or
ResponseEntity<?>object,用来提供使用Servlet中HTTP中response中的headers和contents.通过HttpMessageConverters把entity的body转换成response流.
9. An
HttpHeadersobject,返回reponse没有body.
10. A
Callable<?>object,当Spring MVC管理的一个应用想要通过异常的形式返回参数。
11. A
DeferredResult<?>,当应用想要通过它选择的线程来产生返回值,可以使用这个参数。
12. A
ListenableFuture<?>,当应用想要通过它选择的线程来产生返回值,可以使用这个参数。
13. A
ResponseBodyEmitter,使用异步的方法写多个对象到response中可以返回这个类型;同样也支持作为
ResponseEntity的body.
14. An
SseEmitter,可以返回用于写异步服务器发送的事件给response;同样也支持作为
ResponseEntity的body.
15. A
StreamingResponseBody,可以返回用于异步的写入response的OutputStream;同样也支持作为
ResponseEntity的body.
16. Any other return type,被认为是做为是暴露的view中的model属性。可以在方法级别使用
@ModelAttribute用来指定属性名称.(默认的属性名称是返回类型的class name).这个model隐含command对象和
@ModelAttribute注释的结果.
3、@RequestParam – Binding request parameters to method parameters
在Controller中可以使用@RequestParam绑定请求参数到方法的参数。
下面的代码片段展现它的用法:
@Controller @RequestMapping("/pets") @SessionAttributes("pet") public class EditPetForm { // ... @RequestMapping(method = RequestMethod.GET) public String setupForm(@RequestParam("petId") int petId, ModelMap model) { Pet pet = this.clinic.loadPet(petId); model.addAttribute("pet", pet); return "petForm"; } // ... }
如果方法中参数使用了这个@RequestParam,那么request中必须有对应的参数.当然你也可以通过设置@RequestParam的
required属性是
false来指定这个参数不是强制request需要传递这个参数。(e.g.,
@RequestParam(path="id", required=false))如果方法中的参数不是
String类型,Spring MVC会进行自动转换。
当
@RequestParam注解使用到
Map[String, String]或者
MultiValueMap[String, String]类型时,这个map会用request中的所有参数来填充。
4、@RequestBody – Mapping the request body
方法参数中使用@RequestBody表明,这个方法中的参数是使用HTTP请求中的request中的body中的值。(当你使用传json给后面的时候,可以使用这个注解把这个json转换成被注解的对象).例如:
@RequestMapping(path = "/something", method = RequestMethod.PUT) public void handle(@RequestBody String body, Writer writer) throws IOException { writer.write(body); }
你使用一种
HttpMessageConverter把HTTP的request中的body转换成方法参数。
HttpMessageConverter的作用是把HTTP的request中的信息转换成一个对象和把一个对象转换成HTTP的response中的body.Spring MVC中的
RequestMappingHandlerAdapter默认支持
@RequestBody使用下面的
HttpMessageConverters:
1.
ByteArrayHttpMessageConverterconverts byte arrays.
2.
StringHttpMessageConverterconverts strings.
3.
FormHttpMessageConverterconverts form data to/from a MultiValueMap[String, String>.
4.
SourceHttpMessageConverterconverts to/from a javax.xml.transform.Source.
如果你想使用Spring MVC中更多的信息转换,可以使用Spring MVC中的namespace与Spring MVC的Java config来进行注册。如果你打算读/写XML,你需要配置
MarshallingHttpMessageConverter通过
org.springframework.oxm包下面的
Marshaller与
Unmarshaller的实现类。下面的就是使用Spring MVC的namespace的例子:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <util:list id="beanList"> <ref bean="stringHttpMessageConverter"/> <ref bean="marshallingHttpMessageConverter"/> </util:list> </property </bean> <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <property name="marshaller" ref="castorMarshaller"/> <property name="unmarshaller" ref="castorMarshaller"/> </bean> <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
当你在方法参数上使用
@RequsetBody时还可以使用
@Valid来注解它。在这种情况下,它将会使用配置了的
Validator的实例来验证这个对象。当使用Spring MVC的namespace或者使用java config的时候,JSR-303 validator会自动检测classpath中的JSR-303的实现是可用的。
与注解了
@ModelAttribute的参数一样,
Errors可以用来检查errors.如果这样的argument没有声明,就会报
MethodArgumentNotValidException异常。这个异常会被
DefaultHandlerExceptionResolver处理,将会发送
400错误给客户端。
5、@ResponseBody – Mapping the response body
@ResponseBody注解的用法与
@RequestBody相似,这个注解可以用在一个方法上,用来表明这个方法的返回值将会直接写到HTTP的response的body中。(不会被放在Model或者被认为是一个页面名称).例如:
@RequestMapping(path = "/something", method = RequestMethod.PUT) @ResponseBody public String helloWorld() { return "Hello World"; }
上面的例子将会导致
"Hello Word"被写入HTTP的response流中。说得通俗一点就是返回一个Json格式给client.与
@RequestBody一样,Spring MVC能够使用
HttpMessageConverter把方法的返回对象转换成HTTP的response的body。
6、@RestController – Creating REST Controllers
这是一个非常常见的用例用于Controller实现一个REST API,因此只为JSON、XML或自定义MediaType。你现在不需要在你的所有注解了@RequestMapping的方法上使用
@ResponseBody,你只需要在你的Controller类上面使用
@RestController代替使用
Controller。
@RestController是
@ResponseBody与
@Controller结合体的模板注解.不仅如此,它还使得controller具有更多的意义。也可能在将来的框架版本中携带额外的语义。与常规的@Controllers一样,
@RestController也可以通过
@ControllerAdvice来协助.
7、Using HttpEntity
HttpEntity与
@RequestBody和
@ResponseBody类似。除了有权使用request和response的body之外,
HttpEntity(与response特殊实现类ResponseEntity)同样允许有权使用request与response的headers,例如:
@RequestMapping("/something") public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws UnsupportedEncodingException { String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader")); byte[] requestBody = requestEntity.getBody(); // do something with request header and body HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set("MyResponseHeader", "MyValue"); return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED); }
在上面的例子中,获取request header中
MyRequestHeader的值,并且读取读取request的bosy作为一个byte array.它添加
MyResponseHeader到response中,把
"Hello World"写入到response流中,并且设置response的status code为201(Created).
与
@RequestBody和
@ResponseBody一样,Spring使用
HttpMessageConverter把输入数据转换到request与response的流当中.
8、@ModelAttribute on a method
注解@ModelAttribute可以应用到方法上也可以应用在方法参数上。这个章节将介绍它在方法上的用法,下个章节将会介绍它在方法参数上的用法。
当
@ModelAttribute用在方法上时表明这个方法目的是添加一个或者多个model属性。这种方法支持相同的参数类型作为
@RequestMapping方法但不能直接映射到请求。反而在一个Controller中注解了
@ModelAttribute的方法会比同一个controller中
@RequestMapping方法早调用.下面有两个例子:
// Add one attribute // The return value of the method is added to the model under the name "account" // You can customize the name via @ModelAttribute("myAccount") @ModelAttribute public Account addAccount(@RequestParam String number) { return accountManager.findAccount(number); } // Add multiple attributes @ModelAttribute public void populateModel(@RequestParam String number, Model model) { model.addAttribute(accountManager.findAccount(number)); // add more ... }
@ModelAttribute方法用于填充Modle通常需要的属性,例如填充下拉状态或pet类型,检索一个像帐户的命令对象为了使用它来代表一个HTML表单上的数据.在下一节中进一步讨论后一种情况。
注意
@ModelAttribute方法的两种风格.首先,添加一个属性的方法隐式返回它.第二,该方法接受一个
Model并为这个Modle添加任意数量的属性。你可以根据你的需求任意的选择这两种风格。
在一个Controller中可以有许多个
@ModelAttribute方法。在同一个Controller中,这些方法总是比
@RequestMapping方法先被调用。
@ModelAttribute方法同样也可定义在一个标注了
@ControllerAdvice的类上。这些方法可以应用于多个Controller上。你可以看
"@ControllerAdvice -- Advising controllers"章节获取更多信息.
@ModelAttribute注解也能够使用到
@RequestMapping方法上.在这种情况下,
@RequestMapping方法的返回值被解释为一个Model的属性而不是视图名称。视图名称来源于视图名称转换相反就像方法返回void. – Section 21.13.3, “The View - RequestToViewNameTranslator”. // TODO
9、@ModelAttribute – on a method argument(bathPath,casInfo)
在上一个章节中@ModelAttribute可以被应用到方法与方法参数上.这个章节将介绍它在方法参数上的用法.一个
@ModelAttribute方法参数表明参数可以从Model中重新取回。如果没有从Model中取出,这个内容将会第一时间初始化并且添加到Model中.一旦出现在模型中,参数的字段应该填充所有请求参数匹配的名称。在Spring MVC中这被称为数据绑定.一个非常用有的机制,节省你不必逐个解析每个表单字段。
@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) public String processSubmit(@ModelAttribute Pet pet) { }
鉴于上面的例子可以Pet实例从何而来?有下面几种可能:
1. 由于
@SessionAttributes的使用,它可能已经在Model中. – 看下面的章节,叫做
"@SessionAttributes -- store model attributes in the HTTP session between requests."
2. 在同一个Controller中由于使用了
@ModelAttribute方法,可能已经在Model中. – 在上面的章节中已经解释过了.
3. 它可能已经在URI模板变量或者type转换中获取到了.
4. 它可以已经使用它的默认constructor初始化好了。
一个
@ModelAttribute方法是一种通常的方法用来从database获取属性。通过使用
@SessionAttributes这可以被存储在这个请求之间.大多数情况下,它可以很方便的从URI模板变量或者type转换中获取这个属性.下面就是一个例子:
@RequestMapping(path = "/accounts/{account}", method = RequestMethod.PUT) public String save(@ModelAttribute("account") Account account) { }
在这个例子中,model属性的名称(“account”)与URI模板变量的名称相匹配.如果你注册
Converter[String, Account],那么就可以把字符串类型类型account值转换成一个
Account实例,然后上面的例子将会在不需要
@ModelAttribute方法前提下运行.
下一步就是数据绑定,
WebDataBinder这个类匹配request参数名 – 包含query的String类型的参数以及form字段 – model属性字段名.匹配字段在必须的类型转换(String类型到目标fiedl类型)之后进行填充.Controller级别的自定义数据绑定将会在
"Customizing WebDataBinder initialization."章节中细说。
当进行数据绑定的时候可能会有一些错误,比如说:缺少必须的fields或者类型转换errors。你如果需要check这个errors,可以再
@ModelAttribute参数后面添加一个
BindingResult参数:
@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { if (result.hasErrors()) { return "petForm"; } // ... }
在上面的例子中,你可以使用
BindingResult来check在渲染同个一表单的时候是否出错了.而且你可以使用Spring的
<errors>form标签来展现错误.除了数据绑定你也可以通过
BindingResult来使用自己的自定义验证器.这个对象被用来记录数据绑定发生的错误.它允许数据绑定与验证数据的错误被放置在同一个地方,然后报告给用户.
@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { new PetValidator().validate(pet, result); if (result.hasErrors()) { return "petForm"; } // ... }
或者你可以自动调用验证通过添加JSR-303中的
@Valid注解:
@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) { if (result.hasErrors()) { return "petForm"; } // ... }
10、@SessionAttributes – store model attributes in the HTTP session between requests
类级别的注解@SessionAttributes声明session属性被一个特殊的handler使用.代表的用法是遍历model属性的name,或者model属性的类型.它们将会被储存在session中或者进行会话储存.主要用于后续请求的form表单需要的bean.
下面的代码片段展示了这个注解的用法,并且指明了model属性的名称:
@Controller @RequestMapping("/editPet.do") @SessionAttributes("pet") public class EditPetForm { // ... }
11、Working with “application/x-www-form-urlencoded” data
前一节介绍了从浏览器客户端使用@ModelAttribute支持表单提交请求.这个注释同样也推荐用来处理自非浏览器客户端的请求。然而当使用HTTP的PUT请求时,会有一个显著的不同.浏览器可以通过HTTP的GET或者POST来提交表单数据.非浏览器客户端还能够通过HTTP的PUT请求来提交表单数据.这提出了一个挑战,因为在Servlet规范要求
ServletRequest.getParameter*()的一系列方法只支持HTTP的POST请求来储存表单字段,而不是HTTP的PUT请求.
为了支持HTTP的PUT请求或者PATCH请求,
spring-web模块提供了filter –
HttpPutFormContentFilter.你可以在
web.xml中做以下配置:
<filter> <filter-name>httpPutFormFilter</filter-name> <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class> </filter> <filter-mapping> <filter-name>httpPutFormFilter</filter-name> <servlet-name>dispatcherServlet</servlet-name> </filter-mapping> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet>
上面的filter会拦截HTTP中的PUT与PATCH请求通过在content的类型为
"application/x-www-form-urlencoded",读取表单request的body中的表单数据.并且包装
ServletRequest类,为了表单数据可以通过ServletRequest.getParameter*()系列方法来获取.
注意:因为
HttpPutFormContentFilter需要消费request的body,它不应该为
"application/x-www-form-urlencoded"被配置PUT或PATCH依赖其他转换器的url.其中包括
@RequestBody ````MultiValueMap[String, String>和
HttpEntity[MultiValueMap[String, String>>.
12、@CookieValue – Mapping cookie values
@CookieValue注解被来用方法参数绑定HTTP中的cookie值.让我们来看一下下面这个被request接收的cookie.
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
下面的例子是如何获取
JSESSIONID这个cookie值:
@RequestMapping("/displayHeaderInfo.do") public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) { //... }
如果方法参数不是String类型,Spring会自动进行类型转换.具体可以看”Method Parameters And Type Conversion”.这个标签支持Servlet与Portlet环境下的handler方法.
13、@RequestHeader – Mapping request header attributes
@RequestHeader注解允许方法参数绑定request中的header.
下面是一个简单的request的header:
Host localhost:8080 Accept text/html,application/xhtml+xml,application/xml;q=0.9 Accept-Language fr,en-gb;q=0.7,en;q=0.3 Accept-Encoding gzip,deflate Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive 300
下面的代码就是简单的展示如何获取headers中
Accept-Encoding与
Keep-Alive的值:
@RequestMapping("/displayHeaderInfo.do") public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive") long keepAlive) { //... }
如果方法参数不是
String类型,Spring会自动进行类型转换.具体可以看
"Method Parameters And Type Conversion".当
@RequestHeader注解的方法参数是
Map[String, String>,
MultiValueMap[String, String>,或者
HttpHeaders时,这个map会被request中header的所有值自己填充.
注意:Spring MVC内嵌的支持以逗号分隔的String转换成String类型的array/collection或者其它转换系统能够识别的类型.这个标签支持Servlet与Portlet环境下的handler方法.
14、Method Parameters And Type Conversion
从request中取出的String类型的值request参数,path变量,request headers和cookie值可以被用来转换成方法参数或者field(e.g.,使用在@ModelAttribute绑定一个request参数到一个field)的目标类型。如果目标类型不是
String,Spring会自动转换成相应的类型.所有简单的数据类型,比如说int,long,Date等等都是支持的.你甚至可以使用
WebDataBinder来自定义转换处理.(看下面的章节,称为
"Customizing WebDataBinder initialization")或者通过
FormattingConversionService注册
Formatters。
15、Customizing WebDataBinder initialization
可以通过Spring的WebDataBinder来自己请求参数绑定的自定义属性操作.你可以使用
@InitBinder注解在你的Controller中的方法中,在
@ControllerAdvice注解的类上使用
@InitBinder方法,或者提供自定义的
WebBindingInitializer。更多细节可以看看下面的章节,
"@ControllerAdvice -- Advising controllers".
init-binder方法支持所有的
@RequestMapper支持的参数,除了command/form对象和相应的验证结果对象.init-binder方法必须有返回值.但是它们通常被声明为
void。典型的参数包括
WebDataBinder与
WebRequest或者
java.util.Locale的结合,允许代码注册特殊的上下文来编辑.
下面就是一个简单的例子用来表示
@InitBinder为所有的
java.util.Date类型的表单对象配置一个
CustomDateEditor:
@Controller public class MyFormController { @InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); } // ... }
在Spring4.2中,一般考虑使用
addCustomFormatter来指定
Formatter的实现来代替
PropertyEditor的实例.这个特别的重要如果你碰巧有一个基本的
Formatter需要设置在一个共享
FormattingConversionService,用同样的方法来重用特殊的controller调整的绑定规则。
@Controller public class MyFormController { @InitBinder public void initBinder(WebDataBinder binder) { binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd")); } // ... }
16、Configuring a custom WebBindingInitializer
在进行数据绑定的时候,你可以提供一个自定义的WebBindingInitializer实例的实例.你可以通过配置
WebBindingInitializer来实现.但是这样会覆盖默认的配置.
下面的例子是来自于PetClinic应用,展示了使用自定义的
WebBindingInitializer实现的实例.
org.springframework.samples.petclinic.web.ClinicBindingInitializer,通过几个PetClinic的Controller配置必须的属性编辑器。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="cacheSeconds" value="0"/> <property name="webBindingInitializer"> <bean class="org.springframework.samples.petclinic.web.ClinicBindingInitializer"/> </property> </bean>
@InitBinder方法同样能够定义在注解了
@Controller的类上面,它就会适用于匹配的controllers。Spring提供使用
WebBindingInitializer.具体细节可以看下一个章节,叫做
"@ControllerAdvice -- Advising controllers".
17、@ControllerAdvice – Advising controllers
@ControllerAdvice注解是一个component的注解,它允许应用类被classpath自动扫描到.它也能够使用MVC namespace或者MVC Java config。
一个类如果被
@ControllerAdvice注解,那么它可以包含
@ExceptionHandler,
@InitBinder和
@ModelAttribute注解的方法。并且这些方法将应用到所有的Controller级别的
@RequestMapping方法中。而不是在他们宣布控制器层次结构。
@ControllerAdvice注解同样可以用它的属性来指定一个controlers的一个子集.
// Target all Controllers annotated with @RestController @ControllerAdvice(annotations = RestController.class) public class AnnotationAdvice {} // Target all Controllers within specific packages @ControllerAdvice("org.example.controllers") public class BasePackageAdvice {} // Target all Controllers assignable to specific classes @ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class}) public class AssignableTypesAdvice {}
Check out the @ControllerAdvice documentation for more details.
18、Jackson Serialization View Support
有时候需要过滤的将序列化的对象上下文到HTTP中的resonse的body。实了提供这个功能,Spring MVC已经内置了 Jackson’s Serialization Views翻译。在controller的方法中使用
@RequestBody或者controller的方法返回
ResponseEntity,添加
@JsonView注解到class上表明表明这个view类或者interface已经使用了.
@RestController public class UserController { @RequestMapping(path = "/user", method = RequestMethod.GET) @JsonView(User.WithoutPasswordView.class) public User getUser() { return new User("eric", "7!jd#h23"); } }
public class User { public interface WithoutPasswordView {}; public interface WithPasswordView extends WithoutPasswordView {}; private String username; private String password; public User() { } public User(String username, String password) { this.username = username; this.password = password; } @JsonView(WithoutPasswordView.class) public String getUsername() { return this.username; } @JsonView(WithPasswordView.class) public String getPassword() { return this.password; } }
注意:
@JsonView允许多个类被指定,但是使用到controller方法上只能支持一个class。考虑使用一个复合interface,如果需要支持多个视图。
Controller依赖视图解析,只需序列化视图类添加然后添加到模型:
@Controller public class UserController extends AbstractController { @RequestMapping(path = "/user", method = RequestMethod.GET) public String getUser(Model model) { model.addAttribute("user", new User("eric", "7!jd#h23")); model.addAttribute(JsonView.class.getName(), User.WithoutPasswordView.class); return "userView"; } }
19、Jackson JSONP Support
为了使@ResponseBody和
ResponseEntity方法支持JSONP,声明
@ControllerAdvicebean继承
AbstractJsonpResponseBodyAdvice.如下所示的构造函数参数表明JSONP查询参数名称(s):
@ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice { public JsonpAdvice() { super("callback"); } }
controllers依赖view解析,当request的请求参数中有一个叫做
"jsonp"或者
"callback"的时候
JSONP会自动激活。这些名称可以通过
jsonpParameterNames的property文件来定制属性。
相关文章推荐
- android笔记:Service
- 04 Android的系统结构(从01开始点点入门,视频+笔记)
- 关于软键盘的遮挡布局问题几点处理
- 安卓学习-WebView
- 安卓学习-AsyncTask
- Android页面跳转动画简介
- Android的几种消息通信对比
- 关于unity5烘焙过程的详细说明-文档搬运。
- android-基础知识整理-数据存储(未完)
- iOS--Segment的简单定制
- 如何让Android service进程变成前台进程
- 3.支付的回调统一处理
- Android 第一个NDK
- [android] 练习使用ListView(二)
- 自己的Android应用中调起支付宝网页
- Android 中BaseActivty
- Android 中MyApplication
- android之MP3播放器(1)
- 问题锦囊之WS_MOBILE_PAY_SDK_BASE
- Android Studio 快捷键