2017-02-27 31 views
0

我有一个Angular 2服务登载有登录数据到Spring Boot@RestContoller怎样才能从一个Spring引导应用程序的HTTP POST请求

登录请求身体POJO:

{"_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 
} 

但是,当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 Security的UserDetailsS​​ervice中的implmentation抛出UsernameNotFoundException。使用调试器,我可以手动解析请求中的值并将值设置为POJO。这样做后,请求就完成了,所以看起来很清楚问题出在解组阶段。

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

回答

1

这是由于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标注添加到方法PARAM

@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); 
    } 
} 
+0

感谢您的输入。我按照建议添加了注释,但没有成功。没有改变,默认的构造函数仍然被调用。注释掉默认构造函数揭示了原因--Spring创建了POJO参数。定制解串器是唯一真正的选择吗? –

+0

@TheHeadRush你对“Spring创建POJO”有何意义?它应该工作。你不需要一个自定义的反序列化器,这是非常基础的。您正在使用老版本的jackson-datatype-son-org。包括jackson-core,jackson-databind和jackson-annotations的相关性(v2.8.6)。当你提出要求时你的方法被击中了吗?你是否设置了内容类型标题?看来Spring认为它不需要转换请求体 – alfcope

+0

当我说“Spring创建POJO”时,我的意思是故意失败的POJO实例化(通过注释掉默认构造函数)导致不包含引用Jackson的帧的堆栈跟踪。更新了'jackson-datatype-son-org'的依赖关系。三个Jackson罐子的v2.8.6增加了显式的依赖关系。预期的控制器方法被击中,内容类型头被设置为“application/json”。我很困惑。 –

相关问题