Spring REST, JSON “Can not handle managed/back reference 'defaultReference'” 415 Unsupported Media Type

前端 未结 7 1506
一整个雨季
一整个雨季 2020-12-28 17:16

I am trying to POST to http://localhost:9095/translators from an AngularJS front-end using Spring boot/Spring RestController backend.

I can do a GET and the response

相关标签:
7条回答
  • 2020-12-28 18:01

    Another great way to solve this problem is with @JsonView. The idea is that you label your controller with a view name and then label the properties you wish to be displayed for that view. You specifically do not expose the backreferenced properties to the calling view. An extremely simplified example below:

    Imagine you had a 1 to 1 relationship like this. This would create a circular reference.

    @Entity
    public class Student {
    
      String name;
      Tutor tutor;
    
    }
    
    @Entity
    public class Tutor {
      String name;
      Student student;
    
    }
    

    You could now create views for them, almost the same way you do with @JsonIgnore and @JsonProperty.

    Step 1. Create arbitrary empty interfaces that you can use to tag your controllers.

    public class LearningController {
    
      @GetRequest("/tutors")
      @JsonView(TutorView.class) // create an empty interface with a useful name
      public Set<Tutor> tutors() {
        return tutorRepository.findAll()
      }
    
      @GetRequest("/students")
      @JsonView(StudentView.class) // create an empty interface with a useful name
      public Set<Student> students() {
        return studentRepository.findAll()
      }
    }
    

    Step 2. Label the properties you want to expose (in any related / referenced class) to the view, also using the @JsonView annotation.

    @Entity
    public class Student {
    
      @JsonView({StudentView.class, TutorView.class})
      String name;
    
      @JsonView({StudentView.class}) // Not visible to @TutorView (no backreference)
      Tutor tutor;
    
    }
    
    @Entity
    public class Tutor {
      @JsonView({StudentView.class, TutorView.class})
      String name;
      @JsonView(TutorView.class) // Not visible to @StudentView (no backreference)
      Student student;
    }
    
    0 讨论(0)
  • 2020-12-28 18:03

    You need @ResponseBody annotation like as follows:

    @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);
        }
    
    0 讨论(0)
  • 2020-12-28 18:08

    I got it solved by getting rid of JsonManagedReference and JsonBackReference and replacing it with JsonIdentityInfo

    0 讨论(0)
  • 2020-12-28 18:15

    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

    0 讨论(0)
  • 2020-12-28 18:17

    As @Sharppoint said in comments, I solved the mine by removing @JsonManagedReference BUT keep @JsonBackReference.

    0 讨论(0)
  • 2020-12-28 18:18

    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.

    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.

    You can solve this by simply removing one of the @JsonBackReference from either Translation/Language classes and replacing it with @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.

    0 讨论(0)
提交回复
热议问题