【问题标题】:How to POST a JSON payload to a @RequestParam in Spring MVC如何在 Spring MVC 中将 JSON 有效负载发布到 @RequestParam
【发布时间】:2016-11-10 18:01:28
【问题描述】:

我正在使用 Spring Boot(最新版本,1.3.6),我想创建一个 REST 端点,它接受一堆参数和 JSON 对象。比如:

curl -X POST http://localhost:8080/endpoint \
-d arg1=hello \
-d arg2=world \
-d json='{"name":"john", "lastNane":"doe"}'

在我目前正在做的 Spring 控制器中:

public SomeResponseObject endpoint(
@RequestParam(value="arg1", required=true) String arg1, 
@RequestParam(value="arg2", required=true) String arg2,
@RequestParam(value="json", required=true) Person person) {

  ...
}

json 参数不会被序列化为 Person 对象。 我得到一个

400 error: the parameter json is not present.

显然,我可以将 json 参数设为 String 并在控制器方法中解析有效负载,但这违背了使用 Spring MVC 的意义。

如果我使用@RequestBody,这一切都有效,但是我失去了在 JSON 正文之外发布单独参数的可能性。

Spring MVC 中有没有办法“混合”普通的 POST 参数和 JSON 对象?

【问题讨论】:

  • 我认为没有办法,我认为混合表单编码数据和 json 数据不是一个好主意。决定是否要接受其中一个。
  • 很多 API(Stripe、Plaid、Stormpath)使用这种方法在逻辑上分离请求数据(例如,如果我正在搜索,我可以将搜索条件放在 Json 表示中并保持分页表单的表单编码位中的数据)。但我明白你的意思。

标签: java rest spring-mvc spring-boot


【解决方案1】:

是的,可以使用 post 方法同时发送参数和正文: 服务器端示例:

@RequestMapping(value ="test", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Person updatePerson(@RequestParam("arg1") String arg1,
        @RequestParam("arg2") String arg2,
        @RequestBody Person input) throws IOException {
    System.out.println(arg1);
    System.out.println(arg2);
    input.setName("NewName");
    return input;
}

在您的客户端上:

curl -H "Content-Type:application/json; charset=utf-8"
     -X POST
     'http://localhost:8080/smartface/api/email/test?arg1=ffdfa&arg2=test2'
     -d '{"name":"me","lastName":"me last"}'

享受

【讨论】:

  • 这没有回答问题,但显示了如何解决 OP 明确表示他们不想使用的解决方法。
【解决方案2】:

您可以通过使用自动连接的ObjectMapperString 中的Converter 注册到您的参数类型来做到这一点:

import org.springframework.core.convert.converter.Converter;

@Component
public class PersonConverter implements Converter<String, Person> {

    private final ObjectMapper objectMapper;

    public PersonConverter (ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public Person convert(String source) {
        try {
            return objectMapper.readValue(source, Person.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

【讨论】:

  • 对于 @RequestParam 带注释的方法参数也很有魅力
【解决方案3】:

您可以使用 RequestEntity。

public Person getPerson(RequestEntity<Person> requestEntity) {
    return requestEntity.getBody();
}

【讨论】:

    【解决方案4】:

    用户:

     @Entity
    public class User {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Integer userId;
        private String name;
        private String password;
        private String email;
    
    
        //getter, setter ...
    }
    

    JSON:

    {"name":"Sam","email":"sam@gmail.com","password":"1234"}
    

    你可以使用@RequestBody

    @PostMapping(path="/add")
    public String addNewUser (@RequestBody User user) {
        User u = new User(user.getName(),user.getPassword(),user.getEmail());
        userRepository.save(u);
        return "User saved";
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-11
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 2019-04-22
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多