J'essaie de POST to http: // localhost: 9095/translators à partir d'un serveur AngularJS à l'aide du backend Spring boot/Spring RestController.
Je peux faire un GET et la réponse est la suivante:
[{"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"}
Lorsque je poste le json ci-dessous, je reçois la réponse error
POST data:
{
firstName: "zen",
lastName: "cv",
emailId: "email",
userType: "TRANSLATOR",
languages : [{languageId:1,languageCode:"gb",source:true}]
}
Erreur:
{
timestamp: 1422389312497
status: 415
error: "Unsupported Media Type"
exception: "org.springframework.web.HttpMediaTypeNotSupportedException"
message: "Content type 'application/json' not supported"
path: "/translators"
}
Je me suis assuré que mon contrôleur possède l'annotation Mediatype correcte.
@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);
}
}
Après quelques recherches et aussi en voyant la sortie du journal, je me rends compte qu'il s'agit d'un message d'erreur trompeur et que le problème se produit lors de la sérialisation/désérialisation de Json.
Dans le fichier de log, je trouve
2015-01-27 21: 08: 32.488 WARN 15152 --- [nio-9095-exec-1] .CjMappingJackson2HttpMessageConverter: Échec de l'évaluation de la désérialisation Pour le type [type simple, classe User ]: Java.lang.IllegalArgumentException: Impossible de gérer les références gérées/arrière 'DefaultReference': type de référence arrière (Java.util.List) non compatible avec le type géré ( Utilisateur)
Voici ma classe utilisateur et traduction de classe (getter, setter, constructeur, etc. omis pour plus de brièveté)
@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;
}
Ma question est la suivante: comment définir correctement JsonManagedReference et JsonBackReference pour les entités ci-dessus? J'ai lu le doc. et je ne peux pas comprendre ce qui ne va pas ici en fonction du message d'erreur
Je l'ai résolu en éliminant JsonManagedReference et JsonBackReference et en le remplaçant par JsonIdentityInfo.
Pour ceux qui demandent, Une autre approche serait d’utiliser JsonIdentityInfo, plus rapide, et d’annoter votre classe avec:
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Account implements Java.io.Serializable {
....
private Long id;
}
* Je n'ai pas eu assez de rep pour commenter.
Comme @Sharppoint l'a dit dans des commentaires, j'ai résolu le problème en supprimant @JsonManagedReference
MAIS conserver @JsonBackReference
.
Vous avez besoin d'une annotation @ResponseBody
comme suit:
@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);
}
J'avais le même bogue et j'ai résolu de supprimer toutes mes annotations @JsonBackReference et @JsonManagedReference, puis j'ai mis @JsonIdentityInfo dans tous mes classements avec des relations Consultez la Documentation