Ich habe folgenden Code:
@Path("/users/{id}")
public class UserResource {
@Autowired
private UserDao userDao;
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public User getUser(@PathParam("id") int id) {
User user = userDao.getUserById(id);
if (user == null) {
throw new NotFoundException();
}
return user;
}
Wenn ich einen Benutzer anfordere, der nicht existiert, wie /users/1234
, mit "Accept: application/json
", gibt dieser Code eine HTTP 404
-Antwort zurück, wie man es erwarten würde, aber Content-Type
setzt auf text/html
und eine Nachricht vom HTML-Code. Die Annotation @Produces
wird ignoriert.
Ist es ein Code-Problem oder ein Konfigurationsproblem?
Ihre @Produces
-Annotation wird ignoriert, da nicht erfasste Ausnahmen von der jax-rs-Laufzeitumgebung mit einer vordefinierten (Standardeinstellung) ExceptionMapper
verarbeitet werden. Wenn Sie die zurückgegebene Nachricht im Falle einer bestimmten Ausnahme anpassen möchten, können Sie eine eigene ExceptionMapper
erstellen, um sie zu behandeln. In Ihrem Fall benötigen Sie einen, der die NotFoundException
-Ausnahme behandelt und den Header "Accept" nach dem angeforderten Antworttyp abfragt:
@Provider
public class NotFoundExceptionHandler implements ExceptionMapper<NotFoundException>{
@Context
private HttpHeaders headers;
public Response toResponse(NotFoundException ex){
return Response.status(404).entity(yourMessage).type( getAcceptType()).build();
}
private String getAcceptType(){
List<MediaType> accepts = headers.getAcceptableMediaTypes();
if (accepts!=null && accepts.size() > 0) {
//choose one
}else {
//return a default one like Application/json
}
}
}
Sie können die Antwortrückgabe verwenden. Beispiel unten:
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response get(@PathParam("id") Long id) {
ExampleEntity exampleEntity = getExampleEntityById(id);
if (exampleEntity != null) {
return Response.ok(exampleEntity).build();
}
return Response.status(Status.NOT_FOUND).build();
}
404 wird von Ihrem Server zurückgegeben, da erwartet wird, dass Sie die Dinge in der folgenden Form übergeben
/users/{id}
aber Sie übergeben es als
/users/user/{id}
welche Ressource existiert überhaupt nicht
versuchen Sie, auf die Ressource als /users/1234
zuzugreifen.
BEARBEITEN:
erstellen Sie eine Klasse wie
class RestResponse<T>{
private String status;
private String message;
private List<T> objectList;
//gettrs and setters
}
falls Sie nun eine Antwort für User
wünschen, können Sie sie wie folgt erstellen
RestResponse<User> resp = new RestResponse<User>();
resp.setStatus("400");
resp.setMessage("User does not exist");
und Unterschrift Ihrer Ruhe-Methode wäre wie folgt
public RestResponse<User> getUser(@PathParam("id") int id)
im Falle einer erfolgreichen Antwort können Sie Dinge einstellen
RestResponse<User> resp = new RestResponse<User>();
List<User> userList = new ArrayList<User>();
userList.add(user);//the user object you want to return
resp.setStatus("200");
resp.setMessage("User exist");
resp.setObjectList(userList);