java - 让Spring使用Jackson在GET端点中转换JSON编码的@RequestParam

标签 java spring spring-mvc jackson

这是我在 stackoverflow 上提出的第一个问题,所以请温柔点:)

现有 GET 端点可转换为 POST。 它需要扩展以接受包含 JSON 编码数据的查询参数 filterKeys。这种方法不是很常见,但一些大型 API 正在使用它。 工作方法是将查询参数映射到字符串,然后使用 Controller 方法中的 Jackson ObjectMapper 反序列化为 Java 对象。 有没有什么方法可以在后台的某个地方应用这个 Jackson 反序列化,就像 Spring 对 @RequestBody 开箱即用的支持一样?

JSON 编码的 filterKeys 示例:

[
  {
    "parameter": "datetime",
    "value": {
      "type": "INT_RANGE",
      "start": 1275782400,
      "end": 1571443199
    }
  },
  {
    "parameter": "value",
    "value": {
      "type": "LONG_RANGE",
      "start": 100,
      "end": 200
    }
  }
]

Java 对象:

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;

import javax.validation.constraints.NotNull;
import java.util.List;

@Getter
@AllArgsConstructor
@JsonInclude
public class FilterKeyRequest {

    @NotNull
    private String parameter;
    @NotNull
    private FilterValue value;

}

我尝试简单地将 filterKeys 映射到 FilterKeyRequest 这当然不起作用。 当前的解决方案是在 Controller 方法内进行反序列化:

@GetMapping("/data")
public List<TransferResponse> getData(@RequestParam(required = false) int someOtherParam,
                                          @RequestParam(required = false) String filterKeys) throws BadFilterKeyParameter {

        List<FilterKeyRequest> filters = List.of();
        try {
            filters = objectMapper.readValue(filterKeys, new TypeReference<List<FilterKeyRequest>>() {});
        } catch (IOException e) {
            throw new BadFilterKeyParameter("The filterKeys parameters couldn't be encoded due do bad JSON format");
        }

        return someService.getData(someOtherParam, filters);
    }

我真的很想在后台某个地方优雅地处理这个问题。以某种方式使用 org.springframework.core.convert.converter.Converter 或 org.springframework.web.method.support.HandlerMethodArgumentResolver 可能是可能的。最好不要显式调用 Jackson 对象映射器。

更新: 我找到了一个带有 Converter 的解决方案,但它仍然意味着显式调用 Jackson ObjectMapper,但我可以接受:

@Slf4j
@RequiredArgsConstructor
@Component
public class FilterKeyConverter implements Converter<String, List<FilterKeyRequest>> {

    private final ObjectMapper mapper;

    @Override
    public List<FilterKeyRequest> convert(String source) {
        List<FilterKeyRequest> filters = List.of();
        try {
            filters = mapper.readValue(source, new TypeReference<List<FilterKeyRequest>>() {});
        } catch (IOException e) {
            log.warn("The parameter couldn't be encoded due do bad JSON encoding");
        }
        return filters;
    }
}

最佳答案

您的 getData() 方法应该在 @RestController 注解的类中定义(而不是 @Controller)

@RestController
public DataController {
    @GetMapping("/data")
    public List<TransferResponse> getData(@RequestParam(required = false) int someOtherParam,
                                          @RequestParam(required = false) String filterKeys) throws BadFilterKeyParameter {

        List<FilterKeyRequest> filters = List.of();
        try {
            filters = objectMapper.readValue(filterKeys, new TypeReference<List<FilterKeyRequest>>() {});
        } catch (IOException e) {
            throw new BadFilterKeyParameter("The filterKeys parameters couldn't be encoded due do bad JSON format");
        }

        return someService.getData(someOtherParam, filters);
    }
}

关于java - 让Spring使用Jackson在GET端点中转换JSON编码的@RequestParam,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58751395/

相关文章:

java - 如何用最少的 jar 集成 BIRT 报表引擎?

ajax - 将 spring 3 mvc 与 GWT 集成的经验?

amazon-web-services - 使用 Spring-Boot MVC 登录的 AWS ELB HTTPS 到 HTTP 不起作用

java - 获取Android中RadioGroup的索引

java - 如何在 TestNG 中生成不同名称的测试?

java - Spring 在基本 Spring Boot 应用程序中找不到 bean

java - commons-fileupload 依赖有什么问题?

java - hibernate + Spring 应用程序。在使用数据库之前添加逻辑

java - 有没有我们可以用来在二进制/字节代码级别比较两个 Jar 的工具?

java - 为什么Tuckey UrlRewrite Filter在规则匹配后不调用chain.doFilter?