2017-02-27 273 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」。我很困惑。 –

相關問題