如何从 Spring 启动应用程序中的 HTTP POST 请求生成 POJO

How Can I Generate a POJO from an HTTP POST Request in a Spring Boot Application

我有一个 Angular 2 服务,可以将登录数据发布到 Spring Boot @RestContoller

登录请求正文:

{"_username": "test", "_password": "test"}

其余控制器:

@RestController
public class AuthControl {
    @Autowired
    AuthenticationService authenticationService;

    @RequestMapping(value = "/someurl", method = RequestMethod.POST)
    public LoginDto authenticate(HttpServletResponse response, LoginRequestDto requestDto) throws IOException, JSONException {
        return authenticationService.authenticate(requestDto, response);
    }
}

Jackson 将请求解组到此 POJO

public class LoginRequestDto {
    private String _username;
    private String _password;

    public LoginRequestDto() { }
    public LoginRequestDto(String u, String p) {
        this._username = u;
        this._password = p;
    }

    // getters and setters
}

但是,当 Jackson 解组 POJO 时,字段值设置为空,而不是 "test"/"test"。结果,登录尝试失败并显示错误的凭据消息。我想知道我是否缺少库或导致这些字段设置不正确的原因。

来自 pom.xml

的依赖项
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency><!-- implements Thymeleaf HTML5 parsing -->
        <groupId>net.sourceforge.nekohtml</groupId>
        <artifactId>nekohtml</artifactId>
        <version>1.9.22</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-json-org</artifactId>
        <version>2.4.0</version>
    </dependency>
</dependencies>

唯一记录的异常是我对 Spring 安全性的 UserDetailsS​​ervice 的实现抛出的 UsernameNotFoundException。使用调试器,我可以手动解析请求中的值并将这些值设置到 POJO 中。执行此操作后,请求完成,因此很明显问题出在解组阶段。

如有任何想法或建议,我们将不胜感激。

这是由于 Jackson 在反序列化时默认使用默认构造函数。您需要使用 @JsonCreator 注释让 jackson 知道您要使用哪个构造函数,并使用注释 @JsonProperty 让它知道如何将参数与 json 属性绑定。

public class LoginRequestDto {
    private String _username;
    private String _password;

    public LoginRequestDto() { }

    @JsonCreator
    public LoginRequestDto(@JsonProperty("_username") String u,
                           @JsonProperty("_password") String p) {
        this._username = u;
        this._password = p;
    }

    // getters and setters
}

查看 使用构造函数或工厂方法 部分 jackson-annotations project


更新您的请求映射方法,指定它使用 json 并将 @RequestBody 注释添加到方法参数中

@RestController
public class AuthControl {
    @Autowired
    AuthenticationService authenticationService;

    @RequestMapping(value = "/someurl", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE })
    public LoginDto authenticate(HttpServletResponse response, @RequestBody LoginRequestDto requestDto) throws IOException, JSONException {
        return authenticationService.authenticate(requestDto, response);
    }
}