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

时间:2017-02-27 18:57:29

标签: maven spring-mvc jackson unmarshalling

我有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);
    }
}

杰克逊将请求解组为此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
}

然而,当杰克逊解组POJO时,字段值被设置为空,而不是“测试”/“测试”。因此,登录尝试失败,并显示错误的凭据消息。我想知道我是否错过了一个库或某些导致这些字段设置不当的东西。

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 Security的UserDetailsS​​ervice实施的抛出的UsernameNotFoundException。使用调试器,我可以手动解析请求中的值并将值设置为POJO。执行此操作后,请求完成,因此很明显该问题处于解组阶段。

任何想法或建议都将不胜感激。

1 个答案:

答案 0 :(得分:1)

这是由于Jackson在反序列化时默认使用默认构造函数。您需要使用@JsonCreator注释让jackson知道您要使用的构造函数和注释@JsonProperty,以便让它知道如何将params与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);
    }
}