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的經常使用接口目錄

相關文章
相關標籤/搜索