Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
235 views
in Technique[技术] by (71.8m points)

java - Spring Data REST: Override repository method on the controller

I have the following REST repository, whose implementation is generated at runtime by Spring.

@RepositoryRestResource
public interface FooRepository extends CrudRepository<Foo, Long> {

}

This means that I will have save(), find(), exists() and other methods available and exposed via REST.

Now, I would like to override one of the methods; for example, save(). For that, I would create a controller exposing that method, like so:

@RepositoryRestController
@RequestMapping("/foo")
public class FooController {

    @Autowired
    FooService fooService;


    @RequestMapping(value = "/{fooId}", method = RequestMethod.PUT)
    public void updateFoo(@PathVariable Long fooId) {
        fooService.updateProperly(fooId);
    }

}

The problem: If I enable this controller, then all of the other methods implemented by Spring are not exposed anymore. So, for example, I can no longer do a GET request to /foo/1

Question: Is there a way of overriding REST methods while still keeping the other auto-generated Spring methods?

Extra info:

  1. This question seems very similar: Spring Data Rest: Override Method in RestController with same request-mapping-path ... but I don't want to change the path to something like /foo/1/save

  2. I thought of using a @RepositoryEventHandler but I'm not very fond of that idea because I would like to encapsulate it under a service. Also, you seem to lose control of the transaction context.

  3. This part of the Spring Data documentation says the following:

    Sometimes you may want to write a custom handler for a specific resource. To take advantage of Spring Data REST’s settings, message converters, exception handling, and more, use the @RepositoryRestController annotation instead of a standard Spring MVC @Controller or @RestController

so it seems that it should work out of the box, but unfortunately not.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is there a way of overriding REST methods while still keeping the other auto-generated Spring methods?

Look at the example in the documentation carefully: while not explicitly forbidding class-level requestmapping, it uses method-level requestmapping. I'm not sure if this is the wanted behavior or a bug, but as far as I know this is the only way to make it work, as stated here.

Just change your controller to:

@RepositoryRestController
public class FooController {

    @Autowired
    FooService fooService;

    @RequestMapping(value = "/foo/{fooId}", method = RequestMethod.PUT)
    public void updateFoo(@PathVariable Long fooId) {
        fooService.updateProperly(fooId);
    }

    // edited after Sergey's comment
    @RequestMapping(value = "/foo/{fooId}", method = RequestMethod.PUT)
    public RequestEntity<Void> updateFoo(@PathVariable Long fooId) {
        fooService.updateProperly(fooId);

        return ResponseEntity.ok().build(); // simplest use of a ResponseEntity
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...