How to post a list to Spring Data Rest?

后端 未结 4 1367
情书的邮戳
情书的邮戳 2021-01-04 03:17

I followed this example, which allows to post a unique Person object. I want a REST service where I can post a collection of Person at once, e.g. a

相关标签:
4条回答
  • 2021-01-04 03:44

    Well, AFAIK you can't do that with spring data rest, just read the docs and you will see, that there is no mention about posting a list to collection resource.

    The reason for this is unclear to me, but for one thing - the REST itself doesn't really specify how you should do batch operations. So it's unclear how one should approach that feature, like should you POST a list to collection resource? Or should you export resource like /someentity/batch that would be able to patch, remove and add entities in one batch? If you will add list how should you return ids? For single POST to collection spring-data-rest return id in Location header. For batch add this cannot be done.

    That doesn't justify that spring-data-rest is missing batch operations. They should implement this IMHO, but at least it can help to understand why are they missing it maybe.

    What I can say though is that you can always add your own Controller to the project that would handle /someentity/batch properly and you can even probably make a library out of that, so that you can use it in another projects. Or even fork spring-data-rest and add this feature. Although I tried to understand how it works and failed so far. But you probably know all that, right?

    There is a feature request for this.

    0 讨论(0)
  • 2021-01-04 03:53
    @RequestMapping(method=RequestMethod.POST, value="/batchInsert", consumes = "application/json", produces = "application/json")
    @ResponseBody
    public ResponseEntity<?> batchInsert(@RequestBody Resources<Person> people, PersistentEntityResourceAssembler assembler) throws Exception {
        Iterable<Person> s = repo.save( people.getContent() ); // save entities
    
        List<PersistentEntityResource> list = new ArrayList<PersistentEntityResource>();
        Iterator<Sample> itr = s.iterator();
        while(itr.hasNext()) {
            list.add( assembler.toFullResource( itr.next() ) );
        }
    
        return ResponseEntity.ok( new Resources<PersistentEntityResource>(list) );
    }
    
    0 讨论(0)
  • 2021-01-04 03:55

    Based on user1685095 answer, You can make custom Controller PersonRestController and expose post collection of Person as it seem not exposed yet by Spring-date-rest

    @RepositoryRestController
    @RequestMapping(value = "/persons")
    public class PersonRestController {
    private final PersonRepository repo;
    @Autowired
    public AppointmentRestController(PersonRepository repo) {
        this.repo = repo;
    }
    
    @RequestMapping(method = RequestMethod.POST, value = "/batch", consumes = "application/json", produces = "application/json")
    public @ResponseBody ResponseEntity<?> savePersonList(@RequestBody Resource<PersonWrapper<Person>> personWrapper,
            PersistentEntityResourceAssembler assembler) {
        Resources<Person> resources = new Resources<Person>(repo.save(personWrapper.getContent()));
        //TODO add extra links `assembler`
        return ResponseEntity.ok(resources);
    }
    

    }

    PersonWrapper to fix:

    Can not deserialize instance of org.springframework.hateoas.Resources out of START_ARRAY token\n at [Source: java.io.PushbackInputStream@3298b722; line: 1, column: 1]

    Update

    public class PersonWrapper{
     private List<Person> content;
       
    public List<Person> getContent(){
    return content;
    }
    
    public void setContent(List<Person> content){
    this.content = content;
    }
    }
    
    public class Person{
    private String name;
    private String email;
    // Other fields
    
    // GETTER & SETTER 
    }
    
    0 讨论(0)
  • 2021-01-04 04:03

    I tried to use @RequestBody List<Resource<MyPojo>>. When the request body does not contain any links, it works well, but if the element carries a link, the server could not deserialize the request body.

    Then I tried to use @RequestBody Resources<MyPojo>, but I could not figure out the default name of a list.

    Finally, I tried a wrapper which contained List<Resource<MyPojo>>, and it works.

    Here is my solution:

    First create a wrapper class for List<Resource<MyPojo>>:

    public class Bulk<T> {
        private List<Resource<T>> bulk;
        // getter and setter
    }
    

    Then use @RequestBody Resource<Bulk<MyPojo>> for parameters.

    Finally, example json with links for create bulk data in one request:

    {
        "bulk": [
            {
                "title": "Spring in Action",
                "author": "http://localhost:8080/authors/1"
            },
            {
                "title": "Spring Quick Start",
                "author": "http://localhost:8080/authors/2"
            }
        ]
    }
    
    0 讨论(0)
提交回复
热议问题