Java &引用;“错误请求”;向Rest服务发送JSON对象时

Java &引用;“错误请求”;向Rest服务发送JSON对象时,java,json,spring,rest,Java,Json,Spring,Rest,我正在用JavaSpring编写一个web应用程序。我得到了如下所示的MyUser类和一个RESTAPI public class MyUsers { String username; String password; boolean enabled; Collection<GrantedAuthority> roles; //getters, setters } 通过GET方法,我收到了以下json: { "password":"

我正在用JavaSpring编写一个web应用程序。我得到了如下所示的MyUser类和一个RESTAPI

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

    //getters, setters
}
通过GET方法,我收到了以下json:

{
    "password":"5345345345",
    "enabled":true,
    "roles":[{"authority":"ROLE_ADMIN"}],
    "username":"admin"
}
但是,当我使用POST方法时,我不能指定角色,我只能发送下面的对象,否则我会得到一个“错误请求”错误

我希望能够指定角色。 任何关于如何解决此问题的想法都将受到高度赞赏

编辑:

我试过了,但没用。有错误吗

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
}
公共类UserDeserializer扩展JsonDeserializer{
@凌驾
公共MyUser反序列化(JsonParser JsonParser,反序列化上下文反序列化上下文)
抛出IOException{
MyUser MyUser=new MyUser();
ObjectCodec oc=jsonParser.getCodec();
JsonNode=oc.readTree(jsonParser);
迭代器元素=node.get(“角色”).getElements();
while(elements.hasNext()){
JsonNode next=elements.next();
JsonNode authority=next.get(“authority”);
MyUser.getRoles().add(新的SimpleGrantedAuthority(authority.asText());
}
//System.out.println(MyUser.toString());
返回MyUser;
}
}
@JsonDeserialize(使用=UserDeserializer.class)
公共类MyUser{
字符串用户名;
字符串密码;
布尔启用;
列出角色;
//能手,二传手
}

GrantedAuthority是一个接口,您需要通过这里提到的一种方式向Jackson库通知具体类


根据您更新的代码,您已经在
MyUser
类上使用了
@JsonDeserialize
,我认为这是没有必要的,因为Jackson已经知道如何反序列化
MyUser
类中除
角色
字段以外的所有字段。我建议在
角色
字段级别使用
@JsonDeserialize
,这样就不必反序列化整个
MyUser
类,只需Jackson无法反序列化的字段即可

作为一个优势,如果您希望添加新字段,则无需修改自定义反序列化程序,但不更改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;
  }
}

我假设您的类路径中有Jackson 2。

看起来Jackson在反序列化Spring security
GrantedAuthority
对象时有困难。您可以尝试为此使用Jackson自定义反序列化程序。当然,这篇文章可能会对您有所帮助,嗯,我尝试过,但有一些问题,我是否应该将@JsonDeserialize注释放在MyUser类中?是的,因为您必须告诉Jackson使用此特定注释进行反序列化。另一种方法是将Spring在MappingJackson2HttpMessageConverter类中使用的自定义默认对象映射器设置为默认对象映射器,该类用于使用
@ResponseBody
@RequestBody
序列化和反序列化对象。如果需要,您可以使用自己的ObjectMapper创建新的
MappingJackson2HttpMessageConverter
。但第一种方法要容易得多,我想我仍然无法让它工作,似乎反序列化方法并没有被访问。我在问题中添加了代码。
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
}
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;
  }
}
@JsonDeserialize(using = GrantedAuthorityDeserializer.class)
Collection<GrantedAuthority> roles;