【问题标题】:Cannot use Map as a JSON @RequestParam in Spring REST controller无法在 Spring REST 控制器中将 Map 用作 JSON @RequestParam
【发布时间】:2018-06-05 12:01:56
【问题描述】:

这个控制器

@GetMapping("temp")
public String temp(@RequestParam(value = "foo") int foo,
                   @RequestParam(value = "bar") Map<String, String> bar) {
    return "Hello";
}

产生以下错误:

{
    "exception": "org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException",
    "message": "Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Map': no matching editors or conversion strategy found"
}

我想要传递一些带有bar 参数的JSON: http://localhost:8089/temp?foo=7&bar=%7B%22a%22%3A%22b%22%7D,其中foo7bar{"a":"b"} 为什么 Spring 不能进行这种简单的转换?请注意,如果将地图用作@RequestBodyPOST 请求,它会起作用。

【问题讨论】:

标签: spring spring-boot spring-restcontroller http-request-parameters


【解决方案1】:

这是有效的解决方案: 只需将自定义转换器从String 定义为Map@Component。然后会自动注册:

@Component
public class StringToMapConverter implements Converter<String, Map<String, String>> {

    @Override
    public Map<String, Object> convert(String source) {
        try {
            return new ObjectMapper().readValue(source, new TypeReference<Map<String, String>>() {});
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}

【讨论】:

    【解决方案2】:

    如果您想使用Map&lt;String, String&gt;,您必须执行以下操作:

    @GetMapping("temp")
    public String temp(@RequestParam Map<String, String> blah) {
        System.out.println(blah.get("a"));
        return "Hello";
    }
    

    这个网址是:http://localhost:8080/temp?a=b

    使用Map&lt;String, String&gt;,您将可以访问您提供的所有 URL 请求参数,因此您可以添加 ?c=d 并使用 blah.get("c"); 访问控制器中的值

    有关更多信息,请查看:http://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/spring-mvc-request-param/ 部分 将 Map 与 @RequestParam 一起用于多个参数

    更新 1:如果您想将 JSON 作为字符串传递,您可以尝试以下操作:

    如果要映射 JSON,则需要定义相应的 Java 对象,因此对于您的示例,请尝试使用实体:

    public class YourObject {
    
       private String a;
    
       // getter, setter and NoArgsConstructor
    
    }
    

    然后利用 Jackson 的 ObjectMapper 将 JSON 字符串映射到 Java 实体:

    @GetMapping("temp")
    public String temp(@RequestParam Map<String, String> blah) {
         YourObject yourObject = 
              new ObjectMapper().readValue(blah.get("bar"), 
                  YourObject.class);
         return "Hello";
    }
    

    有关更多信息/不同方法,请查看:JSON parameter in spring MVC controller

    【讨论】:

    • 感谢您的回答。我真正想要的是将 JSON 作为参数传递。请参阅我更新的问题。
    • 谢谢,我去看看。我只是希望有一个比明确使用 ObjectMapper 更干净的解决方案。
    • 你能成功映射JSON吗?
    猜你喜欢
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 2018-01-17
    • 2016-07-06
    • 2018-10-04
    • 2014-10-22
    相关资源
    最近更新 更多