先写一个普通的@Controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class Controller {
@GetMapping("/test")
public Object ret(@RequestParam String name){
return name;
}
@GetMapping("/test2")
public Object ret2(@RequestParam String name){
Map<String,Object> map = new HashMap<>();
map.put("NAME",name);
return map;
}
}
这里要求对返回值进行检测,引入@ControllerAdvice
package com.example.demo.controllors;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
@Autowired
private ObjectMapper objectMapper;
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
Map<String,Object> map = new HashMap<>();
map.put("success",true);
map.put("diaoyong",true);
map.put("data",o);
if(o instanceof String){
//如果控制器方法返回类型为字符串,响应的Content-Type为text/plain,手动设置为json,
//并重写为序列化后的json字符串
serverHttpResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
try {
return objectMapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
throw new RuntimeException("json序列化失败",e);
}
}
return map;
}
}
这里实现了ResponceBodyAdvice接口
public class ResponseAdvice implements ResponseBodyAdvice```
里面有两个方法
public boolean supports(MethodParameter methodParameter, Class aClass)
这个方法负责控制是否重写
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
在support方法返回true后 调用beforeBodyWrite重写响应。
运行结果如下:
test传入String 则不做处理(support仍然返回了true,但是这里是吧String转成了json,没有返回新的map)
test2传入了一个map,运行结果如下
最后附上理解。
在controller返回前,框架会看看ControllerAdvice,如果support返回了true,则执行并返回beforeBodyWrite的内容,而不是原来Controller里面的内容。