wake-up-neo.com

Wie gebe ich eine HTTP 404-JSON/XML-Antwort in JAX-RS (Jersey) für Tomcat zurück?

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? 

30
IJR

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
         }
    }
}
30
Svetlin Zarev

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();
}
16
Tiago

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);
0
VD'