How to post a list to Spring Data Rest?

ぃ、小莉子 提交于 2019-11-30 01:17:38

问题


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 list/any collection named Team with numerous Person objects in just one call.

I mean, my question is not exactly about the OneToMany relationship, where you send each person in a REST request. This topic is well answered.

I want to send a collection of Person objects taking advantage of @RepositoryRestResource or another feature from Spring Data Rest. Is this possible with Spring Data Rest or should I workaround by creating a controller, receive the list and parse the Team list to insert each Person?

I found this feature request, which seems to answer that nowadays Spring Rest Data is missing what I am looking for, but I am not sure.

In my business requirement, application A will post a list of orders to application B and I have to save it in database for future processing, so, after reading about Spring Data Rest and making some samples, I found its clean architecture amazing and very suitable for my requirement except for the fact that I didn't figure out how to post a list.


回答1:


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.




回答2:


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 
}



回答3:


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"
        }
    ]
}



回答4:


@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) );
}


来源:https://stackoverflow.com/questions/31374689/how-to-post-a-list-to-spring-data-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!