Spring Boot相当于JAX-RS拦截器

时间:2018-01-22 13:29:19

标签: spring spring-boot jax-rs

我想在杰克逊开始序列化对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;
    }
}

1 个答案:

答案 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);
    }
}