gpt4 book ai didi

json - 如何在 Spring 中包装 JSON 响应

转载 作者:行者123 更新时间:2023-12-04 16:44:22 24 4
gpt4 key购买 nike

假设我在 Spring 中有两组 Controller :

  • /jsonapi1/*
  • /jsonapi2/*

  • 两者都返回要被解释为 JSON 文本的对象。

    我想要某种过滤器来包装来自一组这些 Controller 的响应,以便:
  • 原始响应包含在另一个对象中。

    例如,如果/jsonapi1/count 返回:
    {"num_humans":123, "num_androids":456}

    那么响应应该被包装并返回如下:
    { "status":0,
    "content":{"num_humans":123, "num_androids":456}
    }
  • 如果 Controller 发生异常,则过滤器应捕获异常并报告如下
    { "status":5,
    "content":"Something terrible happened"
    }
  • 来自其他 Controller 的响应保持不变。

  • 我们目前正在自定义传递给 MappingJackson2HttpMessageConverterWebMvcConfigurerAdapter.configureMessageConverters 以执行上述任务。效果很好,只是这种方法似乎不可能选择性地选择它适用的 URL(或 Controller 类)。

    是否可以将这些类型的包装器应用于单个 Controller 类或 URL?

    更新:Servlet 过滤器看起来像是一个解决方案。是否可以选择将哪个过滤器应用于哪个 Controller 方法或哪个 URL?

    最佳答案

    我为此苦苦挣扎了好几天。 @Misha 的解决方案对我不起作用。我终于能够使用 ControllerAdvice 完成这项工作和 ResponseBodyAdvice .

    ResponseBodyAdvice 允许在 Controller 返回的响应上注入(inject)自定义转换逻辑,但在它转换为 HttpResponse 并提交之前。

    这是我的 Controller 方法的外观:

    @RequestMapping("/global/hallOfFame")
    public List<HallOfFame> getAllHallOfFame() {
    return hallOfFameService.getAllHallOfFame();
    }

    现在我想在响应周围添加一些标准字段,例如 devmessageusermessage .该逻辑进入 ResponseAdvice:
    @ControllerAdvice
    public class TLResponseAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
    Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
    ServerHttpResponse response) {
    // TODO Auto-generated method stub
    final RestResponse<Object> output = new RestResponse<>();
    output.setData(body);
    output.setDevMessage("ResponseAdviceDevMessage");
    output.setHttpcode(200);
    output.setStatus("Success");
    output.setUserMessage("ResponseAdviceUserMessage");
    return output;
    }
    }

    实体类如下所示:
    @Setter // All lombok annotations
    @Getter
    @ToString
    public class RestResponse<T> {

    private String status;
    private int httpcode;
    private String devMessage;
    private String userMessage;

    private T data;
    }

    @Entity
    @Data // Lombok
    public class HallOfFame {

    @Id
    private String id;
    private String name;
    }

    要处理异常,只需创建另一个 ControllerAdviceExceptionHandler .使用示例 in this link .

    此解决方案的优点:
  • 它使您的 Controller 保持清洁。您可以支持 Controller 方法的任何返回类型。
  • 您的 Controller 返回类型类不需要按照 AOP 方法的要求扩展某些基类。
  • 您无需使用 HttpServletResponseWrappers 破解 Spring 过滤器。他们提出了性能惩罚。

  • 编辑 - 2019 年 9 月 17 日

    要处理异常,请使用 @ExceptionHandler .引用下面的代码。
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public MyResponseEntity<Object> handleControllerException(HttpServletRequest request, Throwable ex) {
    // default value
    int httpCode = HttpStatus.INTERNAL_SERVER_ERROR.value();

    if(ex instanceof ResourceNotFoundException) {
    httpCode = HttpStatus.NOT_FOUND.value();
    }
    ...
    }

    关于json - 如何在 Spring 中包装 JSON 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24072458/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com