Java @RequestBody不在Rest服务上工作

Java @RequestBody不在Rest服务上工作,java,angularjs,json,spring,rest,Java,Angularjs,Json,Spring,Rest,我正在使用Spring与AngularJS和WildFly一起开发一个web应用程序 我的问题是,我快发疯了,因为注释@requestBody似乎工作不正常 这是我的服务: @ResponseBody @RequestMapping(value = "/keyuser", method = RequestMethod.POST, consumes = "application/json") public KeyProfileUserSummary updateEmployee(@Reques

我正在使用Spring与AngularJS和WildFly一起开发一个web应用程序

我的问题是,我快发疯了,因为注释@requestBody似乎工作不正常

这是我的服务:

@ResponseBody
@RequestMapping(value = "/keyuser", method = RequestMethod.POST,
  consumes = "application/json")
public KeyProfileUserSummary updateEmployee(@RequestBody KeyProfileUserSummary keyUser) {
return null;
}
这是我的对象KeyProfileUserSummary的成员:

private Integer id;
private String login;
private String password;
private String firstname;
private String lastname;
private UserRole userRole;
我不知道发生了什么,但我已经用其他类型的对象测试了这个服务,它工作得很好,但是当定义KeyProfileUserSummary时,它不工作,我收到错误400错误请求。我已经测试过将@RequestBody设置为“Object”,这样至少我可以看到即将发生的事情,并且从我的前端,我得到以下信息:

{id=3, login=aa, password=a, firstname=Martin, lastname=Müller, userRole=ROLE_USER} 
UserRole是一个枚举。重要的是要澄清KeyProfileUserSummary只是KeyProfileUser的摘要版本,但是由于我在响应中得到的所有链接元素,我决定发送这个更轻的类。使用KeyProfileUser进行测试非常有效,我从角度获得JSON对象,并可以将其发回

在角度方面,我没有对这个物体做任何事情。只需在列表中接收它,当按下编辑按钮时,只需将列表中的元素发送回。这是我发送它的方式:

res = $http.post("url.../keyuser", user);
问题是,我让KeyProfileUser的一切工作都非常完美,但由于数据库可能变得非常庞大,引用也相当多,我决定切换到这个较轻的类,但现在我只收到这个错误400错误请求。。。我就要上吊了:P


谢谢你的帮助

如果我猜的话,jackson在反序列化/序列化您的对象方面失败了。下面是我制作的一个util:

import java.io.IOException;
import java.nio.charset.Charset;

import org.springframework.http.MediaType;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class SerializeDeserializeUtil {

    public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(
            MediaType.APPLICATION_JSON.getType(),
            MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

    public static byte[] convertObjectToJsonBytes(Object object)
            throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(Include.NON_NULL);

        return mapper.writeValueAsBytes(object);

    }

    public static <T> T deserializeObject(String jsonRepresentation,
            Class<T> clazz) throws JsonParseException, JsonMappingException,
            IOException {

        ObjectMapper mapper = new ObjectMapper();

        Object obj = mapper.readValue(jsonRepresentation.getBytes(), clazz);

        return clazz.cast(obj);
    }


    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static byte[] convertObjectToJsonBytesWithCustomSerializer(
            Object object, JsonSerializer serializer, Class clazz)
            throws IOException {

        ObjectMapper mapper = new ObjectMapper();

        SimpleModule sm = new SimpleModule();
        sm.addSerializer(clazz, serializer);

        mapper.registerModule(sm);
        mapper.setSerializationInclusion(Include.NON_NULL);

        return mapper.writeValueAsBytes(object);

    }

}
import java.io.IOException;
导入java.nio.charset.charset;
导入org.springframework.http.MediaType;
导入com.fasterxml.jackson.annotation.JsonInclude.Include;
导入com.fasterxml.jackson.core.JsonParseException;
导入com.fasterxml.jackson.databind.JsonMappingException;
导入com.fasterxml.jackson.databind.JsonSerializer;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.module.SimpleModule;
公共类序列化反序列化util{
公共静态最终MediaType应用程序\u JSON\u UTF8=新MediaType(
MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(),Charset.forName(“utf8”);
公共静态字节[]convertObjectToJsonBytes(对象)
抛出IOException{
ObjectMapper mapper=新的ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
返回mapper.writeValueAsBytes(对象);
}
公共静态T反序列化对象(字符串jsonRepresentation,
类clazz)抛出JsonParseException、JsonMappingException、,
IOException{
ObjectMapper mapper=新的ObjectMapper();
Object obj=mapper.readValue(jsonRepresentation.getBytes(),clazz);
返回层铸件(obj);
}
@SuppressWarnings({“unchecked”,“rawtypes”})
公共静态字节[]convertObjectToJsonBytesWithCustomSerializer(
对象对象,JsonSerializer序列化程序,类clazz)
抛出IOException{
ObjectMapper mapper=新的ObjectMapper();
SimpleModule sm=新的SimpleModule();
sm.addSerializer(clazz,serializer);
映射器注册表模块(sm);
mapper.setSerializationInclusion(Include.NON_NULL);
返回mapper.writeValueAsBytes(对象);
}
}
尝试创建一个测试来序列化和反序列化对象。创建一个KeyProfileUserSummary对象并尝试反序列化/序列化,看看jackson是否抱怨

更简单的方法是启用调试日志记录和检查日志文件,默认情况下,您不会看到此类错误


希望有帮助。

试试这个。。可能对你有用

$http({
    method: 'POST',
    url: 'http://localhost:8080/keyuser',
    data: user,
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }}).then(function(result) {
           console.log(result);
       }, function(error) {
           console.log(error);
       });

如果为“org.springframework.web”org.springframework.web.servlet.DispatcherServlet添加调试日志,则应提供导致“400错误请求”错误的详细信息

可以找到有关Wildfly日志记录配置的详细信息

基于您的KeyProfileUserSummary类,我猜问题在于UserRole对象,它在上面的示例中只是
UserRole=ROLE\u USER
。因为它是一个对象,所以应该用大括号括起来,并且必须设置属性名。e、 差不多

userRole = { name = "ROLE_USER"}

如果是枚举,答案可能会有帮助

好的,所以我终于找到了解决方案

在我的KeyProfileUserSummary中,我只有一个构造函数接受KeyProfileUser并将属性设置为摘要版本:

public KeyProfileUserSummary(KeyProfileUser keyProfileUser) {
  this.id = keyProfileUser.getId();
  this.login = keyProfileUser.getLogin();
  this.password = keyProfileUser.getPassword();
  this.firstname = keyProfileUser.getPerson().getFirstname();
  this.lastname = keyProfileUser.getPerson().getLastname();
  this.userRole = keyProfileUser.getUserRole();
}
显然,在dispatchler servlet的第993行设置一个断点(感谢@Clemens Eberwein提供的提示),我意识到当从JSON对象解析时,Jackson解析器需要一个空构造函数!因此,添加它解决了这个问题,效果非常好


注意:对于KeyProfileUser,它工作得很好,因为我们有hibernate的注解@Entity,因此自动创建了空构造函数。

从服务器上得到的错误是什么,我的意思是stacktrace类似于MessageConverter问题?如何在wildfly上启用调试?以前从未做过。。。但是看到这个错误可能会有帮助。你使用的是spring boot吗?我不知道那是什么,我只使用带有wildfly服务器的eclipse。看看这个。但是,要解决上述问题,您可以尝试手动序列化/反序列化对象。只是为了检查它是否如预期的那样工作,但问题是我们的服务对于每个类都能完美地工作,我不想再放置另一层来反序列化对象。。。这个错误肯定是愚蠢的。。。我们有大量引用的复杂类,在这个有6个属性的非常简单的类上,只是不起作用:(感谢提示,但显然它也起作用。我在尝试用delete而不是POST方法删除用户时遇到了同样的问题,实际上我有一些非常类似的问题