Java Spring REST,JSON“无法处理托管/返回引用‘defaultReference’”415 不支持的媒体类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28179369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring REST, JSON "Can not handle managed/back reference 'defaultReference'" 415 Unsupported Media Type
提问by senseiwu
I am trying to POST to http://localhost:9095/translatorsfrom an AngularJS front-end using Spring boot/Spring RestController backend.
我正在尝试使用 Spring boot/Spring RestController 后端从 AngularJS 前端POST 到http://localhost:9095/translators。
I can do a GET and the response is like following:
我可以执行 GET,响应如下:
[{"userId":1,"firstName":"John","lastName":"Doe","emailId":"[email protected]","languages":[{"languageId":1,"languageCode":"gb","source":true}],"translations":[{"translationId":3,"sourceId":1,"sourceText":"Hello","targetId":null,"targetText":null,"translationStatus":"DUE"}],"userType":"TRANSLATOR"}
When I post the below json, I get the errorresponse
当我发布以下 json 时,我收到错误响应
POST data:
发布数据:
{
firstName: "zen",
lastName: "cv",
emailId: "email",
userType: "TRANSLATOR",
languages : [{languageId:1,languageCode:"gb",source:true}]
}
Error:
错误:
{
timestamp: 1422389312497
status: 415
error: "Unsupported Media Type"
exception: "org.springframework.web.HttpMediaTypeNotSupportedException"
message: "Content type 'application/json' not supported"
path: "/translators"
}
I have made sure that my controller has correct Mediatype annotation.
我已确保我的控制器具有正确的 Mediatype 注释。
@RestController
@RequestMapping("/translators")
public class TranslatorController {
@Autowired
private UserRepository repository;
@RequestMapping(method = RequestMethod.GET)
public List findUsers() {
return repository.findAll();
}
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User findUser(@PathVariable Long userId) {
return repository.findOne(userId);
}
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public User addTranslator(@RequestBody User user) {
//translation.setTranslationId(null);
return repository.saveAndFlush(user);
}
@RequestMapping(value = "/{translatorId}", method = RequestMethod.PUT)
public User updateTranslation(@RequestBody User updatedUser, @PathVariable Long userId) {
//updatedTranslation.setTranslationId(translationId);
return repository.saveAndFlush(updatedUser);
}
@RequestMapping(value = "/{translatorId}", method = RequestMethod.DELETE)
public void deleteTranslation(@PathVariable Long translationId) {
repository.delete(translationId);
}
}
After some research and also by seeing log output, I realize that this is a misleading error message and the problem is in fact happening while serializing/deserializing Json
经过一些研究并通过查看日志输出,我意识到这是一个误导性错误消息,实际上在序列化/反序列化 Json 时发生了问题
In log file, I find
在日志文件中,我发现
2015-01-27 21:08:32.488 WARN 15152 --- [nio-9095-exec-1] .c.j.MappingHymanson2HttpMessageConverter : Failed to evaluate deserialization for type [simple type, class User]: java.lang.IllegalArgumentException: Can not handle managed/back reference 'defaultReference': back reference type (java.util.List) not compatible with managed type (User)
2015-01-27 21:08:32.488 WARN 15152 --- [nio-9095-exec-1] .cjMappingHymanson2HttpMessageConverter:无法评估类型[简单类型,类用户]的反序列化:java.lang.IllegalArgumentException:Can not handleArgumentException托管/反向引用“defaultReference”:反向引用类型(java.util.List)与托管类型(用户)不兼容
Here is my class User and class Translation (getter, setter, constructor etc. omitted for brevity)
这是我的类 User 和类 Translation (为简洁起见省略了 getter、setter、constructor 等)
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name = "user_id")
private long userId;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email_id")
private String emailId;
@ManyToMany
@JoinTable(name = "languages_users", joinColumns = { @JoinColumn(name = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "lang_id")})
@JsonManagedReference
private List<Language> languages = new ArrayList<Language>();
@OneToMany(mappedBy = "translator", fetch = FetchType.EAGER)
@JsonManagedReference
private List<Translation> translations;
@Enumerated(EnumType.STRING)
private UserType userType;
}
@Entity
@Table(name = "translations")
public class Translation {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "translation_id")
private Long translationId;
@Column(name = "source_lang_id")
private Long sourceId;
@Column(name = "source_text")
private String sourceText;
@Column(name = "target_lang_id")
private Long targetId;
@Column(name = "target_text")
private String targetText;
@Enumerated(EnumType.STRING)
@Column(name = "status")
private TranslationStatus translationStatus;
@ManyToOne
@JoinColumn(name = "translator_id")
@JsonBackReference
private User translator;
}
My question is this: How can I correctly set JsonManagedReference and JsonBackReference for the above entities? I did read the doc.and I cannot figure out what is wrong here based on the error message
我的问题是:如何为上述实体正确设置 JsonManagedReference 和 JsonBackReference?我确实阅读了文档。我无法根据错误消息找出这里出了什么问题
采纳答案by senseiwu
I got it solved by getting rid of JsonManagedReference and JsonBackReference and replacing it with JsonIdentityInfo
我通过摆脱 JsonManagedReference 和 JsonBackReference 并用 JsonIdentityInfo 替换它来解决它
回答by sndyuk
You need @ResponseBody
annotation like as follows:
您需要@ResponseBody
如下注释:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody public User addTranslator(@RequestBody User user) {
//translation.setTranslationId(null);
return repository.saveAndFlush(user);
}
回答by Simon Lippens
For those asking, an alternative approach would be to use fasterxml's JsonIdentityInfo and to annotate your class with:
对于那些询问的人,另一种方法是使用 fastxml 的 JsonIdentityInfo 并使用以下内容注释您的类:
import com.fasterxml.Hymanson.annotation.JsonIdentityInfo;
import com.fasterxml.Hymanson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Account implements java.io.Serializable {
....
private Long id;
}
*Didnt have enough rep to comment.
*没有足够的代表发表评论。
回答by Benjamin Lucidarme
As @Sharppoint said in comments, I solved the mine by removing @JsonManagedReference
BUT keep @JsonBackReference
.
正如@Sharppoint 在评论中所说,我通过删除@JsonManagedReference
BUT keep解决了我的问题@JsonBackReference
。
回答by Lupita Llamas
I had the same bug, and I resolved removing all my annotations @JsonBackReference and @JsonManagedReference, then I put @JsonIdentityInfo in all my clases with relationships Check the Documentation
我有同样的错误,我解决了删除我所有的注释@JsonBackReference 和@JsonManagedReference,然后我把@JsonIdentityInfo 放在我所有有关系的类中 检查 文档
回答by sai kiran
Can solve this by removing JsonManagedReference
in the base class. @JsonBackReference
does the work to stop recursing infinitely while getting/posting the data from the controller.
可以通过JsonManagedReference
在基类中删除来解决这个问题。@JsonBackReference
在从控制器获取/发布数据的同时停止无限递归的工作。
I am assuming that your Language class has multiple @JsonBackReference
in it. So when you send the user data with two classes included in it, the spring is unable to deserialize the object and map it accordingly.
我假设您的语言课程中有多个@JsonBackReference
。因此,当您发送包含两个类的用户数据时,spring 无法反序列化对象并相应地映射它。
You can solve this by simply removing one of the @JsonBackReference
from either Translation/Language classes and replacing it with @JsonIgnore
/@JsonIdentityInfo
.
您可以通过简单地@JsonBackReference
从 Translation/Language 类中删除其中一个并将其替换为@JsonIgnore
/来解决此问题@JsonIdentityInfo
。
This way, you're literally doing the same mapping but instead, you rule out the multiple @JsonBackReference
to the base class which is clearly pointed out as an error resulting in 415 Unsupported media type exception
.
这样,您实际上是在进行相同的映射,但是您排除了@JsonBackReference
基类的倍数,这被明确指出为导致415 Unsupported media type exception
.