2016-04-03 33 views
1

我正在Java Spring中編寫Web應用程序。我有下面顯示的這個MyUser類和一個其他的API。將JSON對象發送給Rest服務時出現「Bad Request」請求

public class MyUsers { 
    String username; 
    String password; 
    boolean enabled; 
    Collection<GrantedAuthority> roles; 

    //getters, setters 
} 

在UserController的一些方法:

@RequestMapping(value="/users", method = RequestMethod.POST) 
@ResponseStatus(HttpStatus.CREATED) 
ResponseEntity createUser(Principal principal, @RequestBody @Valid MyUser user) { 
    ... 
} 


@RequestMapping(value = "https://stackoverflow.com/users/{username}", method = RequestMethod.GET) 
public @ResponseBody MyUser getUser(HttpServletResponse response, Principal principal, @PathVariable("username") String username) { 

    ... 
} 

從GET方法我收到此JSON:

{ 
    "password":"5345345345", 
    "enabled":true, 
    "roles":[{"authority":"ROLE_ADMIN"}], 
    "username":"admin" 
} 

然而,當我使用POST方法,我不能指定角色,我只能發送一個下面的對象,否則我會收到「錯誤的請求」錯誤。

{ 
    "password":"5345345345", 
    "enabled":true, 
    "roles":[], 
    "username":"admin" 
} 

我希望能夠指定角色。 任何想法如何解決這個問題將不勝感激。

編輯:

我試過這個,但它沒有幫助。有錯誤嗎?

public class UserDeserializer extends JsonDeserializer<MyUser> { 

    @Override 
    public MyUser deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) 
      throws IOException { 

     MyUser MyUser = new MyUser(); 

     ObjectCodec oc = jsonParser.getCodec(); 
     JsonNode node = oc.readTree(jsonParser); 

     Iterator<JsonNode> elements = node.get("roles").getElements(); 
     while (elements.hasNext()) { 
      JsonNode next = elements.next(); 
      JsonNode authority = next.get("authority"); 
      MyUser.getRoles().add(new SimpleGrantedAuthority(authority.asText())); 
     } 
     //System.out.println(MyUser.toString()); 
     return MyUser; 
    } 
} 

@JsonDeserialize(using = UserDeserializer.class) 
public class MyUser{ 
    String username; 
    String password; 
    boolean enabled; 
    List<GrantedAuthority> roles; 

    //getters, setters 
} 
+1

看起來Jackson在反序列化Spring安全'GrantedAuthority'對象方面存在困難。您可以嘗試使用Jackson自定義解串器來實現此目的。 – Bunti

+1

當然[這](http://stackoverflow.com/questions/35724693/jackson-deserialize-object-with-list-of-springs-interface)發佈可能會對你有所幫助, – Bunti

+0

嗯,我試過,但有一些問題,我應該在MyUser類中添加@JsonDeserialize註釋嗎? – Someone

回答

1

提到基於更新後的代碼的方式之一,告知傑克遜圖書館有關具體的類,你用過@JsonDeserializeMyUser類,這是我認爲沒有必要,因爲傑克遜已經知道如何反序列化MyUser類除roles字段以外的所有字段。我建議在roles字段級別使用@JsonDeserialize,這樣您就不必反序列化整個MyUser類,只需要傑克遜無法反序列化的字段。

作爲一個優勢,如果您希望添加新的字段,您不需要修改您的自定義解串器,不改變API並不是一件好事。

這樣的事情就足夠了。

public class GrantedAuthorityDeserializer extends JsonDeserializer<Collection<GrantedAuthority>> { 

@Override 
public Collection<GrantedAuthority> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) 
     throws IOException, JsonProcessingException { 

    JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser); 
    Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
    if (jsonNode.isArray()) { 
     // you may have different serialization logic if you want 
     for (JsonNode node : jsonNode) { 
      authorities.add(new SimpleGrantedAuthority(node.get("authority").asText())); 
     } 
    } 

    return authorities; 
    } 
} 

,並在roles場使用@JsonDeserialize

@JsonDeserialize(using = GrantedAuthorityDeserializer.class) 
Collection<GrantedAuthority> roles; 

我假設你有傑克遜2 classpath中。

相關問題