简体   繁体   English

Spring Boot解析@RequestBody

[英]Spring boot parsing @RequestBody

I have this old endpoint that I am trying to upgrade to using spring boot. 我有这个旧端点,我正在尝试升级为使用Spring Boot。 It is currently used by a few services so I would like to keep it the same. 当前有一些服务使用它,因此我希望保持不变。

The old endpoint accepts a Request Body of userName=1234&password=1234 . 旧端点接受userName=1234&password=1234的请求userName=1234&password=1234

As an example of how it is called is curl -X POST "http://localhost:8080/AuthService/login" -H "accept: */*" -H "Content-Type: application/json" -d "userName=123&password=123" 例如, curl -X POST "http://localhost:8080/AuthService/login" -H "accept: */*" -H "Content-Type: application/json" -d "userName=123&password=123"

How can I get spring to take the Request Body exactly like my old endpoint but map the input into an Object for me? 我如何才能像我的旧端点一样完全接受请求正文,但为我将输入映射到对象呢?

The old endpoint was using Apache Access and is like this. 旧的端点正在使用Apache Access,就像这样。 It was configured to transform any public method in the class into an endpoint. 它被配置为将类中的任何公共方法转换为端点。

public RequestStatus login(String userName, String password) {
    ...
}

I have translated it over to Spring Boot like this 我已经将它翻译成Spring Boot这样

@ApiOperation(value = "To login", response = RequestStatus.class)
@ResponseBody
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<ReturnValue> login(@RequestBody() String info) {
    Login login = new Login(info);
    ....
}


public class Login {

    private String password;
    private String userName;

    public Login(String info) {
        String[] values = info.split("&");
        for (String value : values) {
            String[] pair = value.split("=");
            if (pair.length == 2) {
                switch (pair[0]) {
                    case "password":
                        password = pair[1];
                        break;
                    case "userName":
                        userName = pair[1];
                        break;
                }
            }
        }
    }
}

But that method of transforming the Request Body into the object is really ugly and error prone and I would like to improve it. 但是,将请求主体转换为对象的方法确实很丑陋且容易出错,我想对其进行改进。

Spring boot will automagically map json to objects for you. Spring Boot将自动为您将json映射到对象。 Just delete the parens after your request body annotation, make your parameter type login and delete the constructor from login. 只需在请求正文注释后删除括号,使参数类型登录,然后从登录名中删除构造函数即可。

@ApiOperation(value = "To login", response = RequestStatus.class)
@ResponseBody
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<ReturnValue> login(@RequestBody Login login) {
    ....
}

public class Login {

    private String password;
    private String userName;
    .... // getters
}

First, convert the body to a map: 首先,将身体转换为地图:

public Map<String, String> bodyToMap(String bodyStr) {
  Map<String, String> body = new HashMap<>();
  String[] values = bodyStr.split("&");
  for (String value : values) {
    String[] pair = value.split("=");
    if (pair.length == 2) {
      body.put(pair[0], pair[1]);
    }
  }
  return body;
}

Then use jackson's ObjectMapper to covert the map to your POJO 然后使用杰克逊的ObjectMapper将地图隐藏到您的POJO

ObjectMapper mapper = new ObjectMapper();
Map<String, String> body = bodyToMap(info);
Login loginInfo = mapper.convertValue(body, Login.class);

You can check for more effective queryparam-style string to map converter here (You should, in case you have more legacy endpoints that have the same key like key1=value1_1&key1=value1_2&key2=value2_1 ) : Parse a URI String into Name-Value Collection 您可以在此处检查更有效的queryparam样式的字符串以映射到转换器(如果您有更多具有相同键的旧式端点,例如key1=value1_1&key1=value1_2&key2=value2_1 ): 将URI字符串解析为Name-Value集合

Add consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE to your method and also change you input parameter to a @RequestParam Map. 在方法中添加consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE ,并将输入参数更改为@RequestParam映射。

@RequestMapping(value = "/login", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public @ResponseBody ResponseEntity<ReturnValue> login(@RequestParam Map<String, String> body) {
    String username = body.get("username");
    String password = body.get("password");

    //authenticate etc..

    return ResponseEntity.ok(returnValue);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM