我想在杰克逊开始序列化对JSON的响应之前,将我的@RestController
方法的响应包装到不同的对象结构中。让我们说我使用下面的Spring控制器。
@RestController
@RequestMapping("/api/susu")
public class SusuController {
@RequestMapping(path = "/{id}", method = RequestMethod.GET)
public Susu hello(String id) {
Susu susu = new Susu();
susu.setDate(LocalDate.now());
susu.setName("Peter Pan");
return susu;
}
}
在JEE7中,我使用了JAX-RS拦截器来访问Susu
实例并将其包装起来。
@Provider
@Priority(1)
public class JsonStructureInterceptor implements WriterInterceptor {
private final JsonResponseBuilder jsonResponseBuilder = new JsonResponseBuilder();
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
Susu s = (Susu) context.getEntity(); // read the JAX-RS response entity
JsonObject jsonObjectWithStructure = jsonResponseBuilder.toResponse(s); // wrap it
// add it back into the JAX-RS context
context.setEntity(jsonObjectWithStructure);
context.proceed();
}
}
使用Spring Boot时,如果不使用JAX-RS功能,首选的方法是什么?
更新1:使用HandlerInterceptorAdapter
我在应用程序上下文中添加了以下HandlerInterceptorAdapter
,并调用了postHandle
方法。到目前为止一切正常但我无法弄清楚如何获取Susu
实例以及如何传递包装的实例以进行进一步处理。
@Component
public class SusuHandlerInterceptor extends HandlerInterceptorAdapter {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
Susu s = ; // how to get access to my Susu instance?
Wrapper w = new Wrapper(s);
// how to pass Wrapper instance on?
}
}
更新2:实施ResponseBodyAdvice
我找到了另一种方法,允许我访问控制器操作的返回值。这里的问题是我无法更改返回值的类型。似乎无法将Susu
实例包装在Wrapper
实例中。
@ControllerAdvice
public class JsonFilter implements ResponseBodyAdvice<SusuController.Susu> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public SusuController.Susu beforeBodyWrite(SusuController.Susu body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
return body;
}
}
答案 0 :(得分:1)
实施ResponseBodyAdvice
可让您在转换对象之前对其进行修改。
如果应修改返回类型,则必须省略Generic-types:
@ControllerAdvice
class JsonModifyingAdvice implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
return new WrappedResponse(body);
}
}