2.盘点springmvc的经常使用接口之HandlerMethodReturnValueHandler

2.盘点springmvc的经常使用接口之HandlerMethodReturnValueHandler###

前言

上一章中介绍了HandlerMethodArgumentResolver来处理controller方法的参数绑定问题。一个请求中有入参的绑定处理,那么固然也会有响应参数的处理,这一章就来说讲处理返回对象的接口——org.springframework.web.method.support.HandlerMethodReturnValueHandlerjava

接口说明

public interface HandlerMethodReturnValueHandler {
	//检验是否支持本处理器处理,返回true会执行handleReturnValue
	boolean supportsReturnType(MethodParameter returnType);
  
	//处理返回值的方法,returnValue便是controller方法中的返回值
	void handleReturnValue(Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;

示例1

controllerweb

package com.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.demo.domain.Person;

@Controller
@RequestMapping("demo2")
public class HandlerMethodReturnValueHandlerDemoController {

	@ResponseBody
	@RequestMapping(method = RequestMethod.GET)
	public Person getPerson() {
		Person person = new Person("Bill", "Gates");
		return person;
	}
}

这个controller方法中返回了Person对象,若是使用默认的配置,将会把Person对象以json格式输出。spring

{
  "firstName": "Bill",
  "lastName": "Gates"
}

那是由于使用了@ResponseBody注解,springmvc调用了RequestResponseBodyMethodProcessor,而RequestResponseBodyMethodProcessor实现了HandlerMethodReturnValueHandler接口的handleReturnValue方法。json

@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
                              ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
  throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {

  mavContainer.setRequestHandled(true);

  // Try even with null return value. ResponseBodyAdvice could get involved.
  writeWithMessageConverters(returnValue, returnType, webRequest);
}

看源码可知,RequestResponseBodyMethodProcessor转交给了HttpMessageConverter去处理,具体的是转交给了MappingJackson2HttpMessageConverter,使用Jackson框架把person对象序列化成了json。mvc

实现本身的HandlerMethodReturnValueHandlerapp

package com.demo.mvc.component;

import javax.servlet.http.HttpServletResponse;

import org.springframework.core.MethodParameter;
import org.springframework.util.Assert;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.demo.domain.Person;

public class PersonReturnValueHandler implements HandlerMethodReturnValueHandler {

	@Override
	public boolean supportsReturnType(MethodParameter returnType) {
		return returnType.getParameterType() == Person.class;
	}

	@Override
	public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
		Assert.isInstanceOf(Person.class, returnValue);
		mavContainer.setRequestHandled(true);
		HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
		response.setContentType("text/plain;charset=utf-8");
      	Person person = (Person) returnValue;
		response.getWriter().write("通过HandlerMethodReturnValueHandler输出的person:" + person);
	}
}

其中mavContainer.setRequestHandled(true);标志着这次请求是不是由handler本身控制的,true表示本方法会响应请求。框架

使用本身的实现后,须要去除controller方法上的@ResponseBody注解,由于咱们再也不须要使用默认的处理器。dom

@RequestMapping(method = RequestMethod.GET)
public Person getPerson() {
  Person person = new Person("Bill", "Gates");
  return person;
}

发送请求GET http://localhost:8080/demo2ide

响应获得.net

通过HandlerMethodReturnValueHandler输出的person:Bill Gates

示例2

发挥想象,给controller的方法加上自定义注解辅助返回值响应。

设置Person前缀注解:

package com.demo.mvc.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonPrefix {

	public String value() default "";
}

controller

@PersonPrefix("rich man")
@RequestMapping(method = RequestMethod.GET)
public Person getPerson() {
  Person person = new Person("Bill", "Gates");
  return person;
}

handleReturnValue方法:

@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
  Assert.isInstanceOf(Person.class, returnValue);
  mavContainer.setRequestHandled(true);
  // 获取方法上的注解
  PersonPrefix annotation = returnType.getMethodAnnotation(PersonPrefix.class);
  HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
  response.setContentType("text/plain;charset=utf-8");
  Person person = (Person) returnValue;
  response.getWriter().write(annotation.value() + " : " + person);
}

最后响应:

rich man : Bill Gates

友情连接:

盘点springmvc的经常使用接口目录

相关文章
相关标签/搜索