I use @RestResource in my Spring Data Rest web application. And I would like to custom 404 error of my RestResource.
I'm aware of ControlerAdvice, handler... BUT it doesn't work with RestResource.
I already tried a lot of things :
- Set setThrowExceptionIfNoHandlerFound to true with a bean or in application.properties
- Disable spring.resources.add-mappings=false in application.properties
- Add basePackages or basePackageClass on ControllerAdvice
- Extends RepositoryRestExceptionHandler (but I can't override it because method are package private)
My current source code is :
@RestResource(path="user")
public interface UserRepository extends Repository<User, Long> {
User findById(Long id);
}
-
@EnableWebMvc
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ErrorHandlerController extends ResponseEntityExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
ResponseEntity<?> handleNotFound(ResourceNotFoundException ex) {
ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error");
return new ResponseEntity<>(apiError, apiError.getHttpStatus());
}
}
Edit 1 (my question isn't a duplicate):
I also try to add a new RestControllerAdviceHandler like this (but it doesn't work) :
@RestControllerAdvice
public class RestControllerAdviceHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
return new ResponseEntity<>(" test ", HttpStatus.NOT_FOUND);
}
}
Edit 2 (about spring framework source code):
After more research in spring source code I find the code below. It seems that if entity is not found, no exception is raised, RestResource just returned a new ResponseEntity>(HttpStatus.NOT_FOUND)). Maybe it's really impossible to intercept and customize the Not Found error with RestResource ?
/**
* <code>GET /{repository}/{id}</code> - Returns a single entity.
*
* @param resourceInformation
* @param id
* @return
* @throws HttpRequestMethodNotSupportedException
*/
@RequestMapping(value = BASE_MAPPING + "/{id}", method = RequestMethod.GET)
public ResponseEntity<Resource<?>> getItemResource(RootResourceInformation resourceInformation,
@BackendId Serializable id, final PersistentEntityResourceAssembler assembler, @RequestHeader HttpHeaders headers)
throws HttpRequestMethodNotSupportedException {
return getItemResource(resourceInformation, id).map(it -> {
PersistentEntity<?, ?> entity = resourceInformation.getPersistentEntity();
return resourceStatus.getStatusAndHeaders(headers, it, entity).toResponseEntity(//
() -> assembler.toFullResource(it));
}).orElseGet(() -> new ResponseEntity<Resource<?>>(HttpStatus.NOT_FOUND));
}
org.springframework.web.filter.OncePerRequestFilterand I intercept all response where the body don't start with "{". So all request that are not json formatted. Then, I replace the body of response with a json. I combine request url and statusCode to find the errorMessage. It's not perfect at all but it works... Hope that helps.