"错误请求"将JSON对象发送到Rest服务时

时间:2016-04-03 01:37:43

标签: java json spring rest

我在Java Spring中编写了一个Web应用程序。我有下面显示的MyUser类和其他API。

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


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

   ...
}

UserController中的一些方法:

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

从GET方法中我收到了这个json:

{
    "password":"5345345345",
    "enabled":true,
    "roles":[],
    "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
}

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

编辑:

我试过这个,但它没有帮助。有错吗?

getMovieData( moveID, titleID, runtimeID, plotID ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (xhttp.readyState == 4 && xhttp.status == 200) {
       var fullMovie = JSON.parse(xhttp.responseText)
       var movie = { title: fullMovie.Title, runtime: fullMovie.Runtime, plot: fullMovie.Plot,};
       document.getElementById(titleID).innerText = movie.title;
       document.getElementById(runtimeID).innerText = movie.runtime;
       document.getElementById(plotID).innerText = movie.plot;
    }
  };
  xhttp.open("GET", "http://www.omdbapi.com/?i=" . movieID . "&plot=short&r=json", true);
  xhttp.send();
}

2 个答案:

答案 0 :(得分:1)

GrantedAuthority是一个界面,你需要通过这里提到的方法之一告知杰克逊图书馆具体的课程

http://wiki.fasterxml.com/JacksonFAQ#Deserializing_Abstract_types

答案 1 :(得分:1)

根据您更新的代码,您在@JsonDeserialize课程中使用了MyUser,我认为没有必要,因为杰克逊已经知道如何反序列化MyUser类的所有字段除外roles字段。我建议在@JsonDeserialize字段级别使用roles,这样您就不必反序列化整个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;
  }
}

并在@JsonDeserialize字段

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

我认为你的课程中有杰克逊2。