Reputation: 463
I'm trying to create an abstract class that performs the common REST operations that are required, but can't work out if what I'm trying to do is possible. I've tried a number of approaches, but have stripped the code below right back to how it should work in my head
Classes updated as per suggestions below. Problem now is that the constructor in the concrete class isn't valid, as CustomerRepository isn't assignable to JpaRepository, though it extends that interface.
AbstractRestController
public abstract class AbstractRestController<T> {
private final JpaRepository<T, Serializable> repository;
public AbstractRestController(JpaRepository<T, Serializable> repository) {
this.repository = repository;
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<JsonResponseBody<T>> getOne(@PathVariable Long id) {
T restObj = repository.findOne(id);
JsonResponseBody<T> response = new JsonResponseBody<>(ResponseStatus.SUCCESS, restObj);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(response);
}
protected JpaRepository<T, Serializable> getRepository() {
return repository;
}
}
CustomerController
@RestController
@RequestMapping(value = "/api/v1/customer")
public class CustomerController extends AbstractRestController<Customer> {
@Autowired
public CustomerController(CustomerRepository repository){
super(repository);
}
}
CustomerRepository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
}
Upvotes: 1
Views: 2114
Reputation: 7169
Indeed, as @dino-tw mentions, you are trying to instantiate an abstract class with an undefined dependency. You can absolutely have an abstract controller class, and even define request handling methods that will be inherited by all subclasses. Try this instead:
public abstract class AbstractRestController<T, ID extends Serializable> {
private final JpaRepository<T, ID> repository;
public AbstractRestController(JpaRepository<T, ID> repository){
this.repository = repository;
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<JsonResponseBody<T>> getOne(@PathVariable ID id) {
T restObj = repository.findOne(id);
JsonResponseBody<T> response = new JsonResponseBody<>(ResponseStatus.SUCCESS, restObj);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(response);
}
protected JpaRepository<T, ID> getRepository(){ return repository; }
}
@RestController
@RequestMapping(value = "/api/v1/customer")
public class CustomerController extends AbstractRestController<Customer, Long> {
@Autowired
public CustomerController(CustomerRepository repository){
super(repository);
}
}
Upvotes: 6