我有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的UserDetailsService实施的抛出的UsernameNotFoundException。使用调试器,我可以手动解析请求中的值并将值设置为POJO。执行此操作后,请求完成,因此很明显该问题处于解组阶段。
任何想法或建议都将不胜感激。
答案 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);
}
}