JAX-RS — JSON과 HTTP 상태 코드를 함께 반환하는 방법?


248

REST 웹 응용 프로그램 (NetBeans 6.9, JAX-RS, TopLink Essentials)을 작성 중이며 JSON HTTP 상태 코드 를 반환하려고 합니다. HTTP GET 메소드가 클라이언트에서 호출 될 때 JSON을 반환하는 코드 준비 및 작업이 있습니다. 본질적으로 :

@Path("get/id")
@GET
@Produces("application/json")
public M_機械 getMachineToUpdate(@PathParam("id") String id) {

    // some code to return JSON ...

    return myJson;
}

그러나 나는 또한 JSON 데이터와 함께 HTTP 상태 코드 (500, 200, 204 등)을 반환합니다.

나는 사용하려고했다 HttpServletResponse:

response.sendError("error message", 500);

그러나 이것은 브라우저가 "진짜"500이라고 생각하게하여 출력 웹 페이지는 일반적인 HTTP 500 오류 페이지였습니다.

클라이언트 측 JavaScript가 이에 따라 일부 논리를 처리 할 수 ​​있도록 HTTP 상태 코드를 반환하려고합니다 (예 : 오류 코드 및 메시지를 HTML 페이지에 표시). 이것이 가능합니까 아니면 HTTP 상태 코드를 사용해서는 안됩니까?


2
당신이 원하는 500 (unreal? :))과 real 500의 차이점은 무엇입니까?
면도칼

@razor 여기서 실제 500은 JSON 응답 대신 HTML 오류 페이지를 의미합니다
Nupur

웹 브라우저는 JSON과 함께 작동하도록 설계되지 않았지만 HTML 페이지에서는 작동하므로 500 (및 일부 메시지 본문)으로 응답하면 브라우저는 오류 메시지 (실제로 브라우저 구현에 따라 다름)를 표시 할 수 있습니다. 일반 사용자.
면도기

답변:


347

예를 들면 다음과 같습니다.

@GET
@Path("retrieve/{uuid}")
public Response retrieveSomething(@PathParam("uuid") String uuid) {
    if(uuid == null || uuid.trim().length() == 0) {
        return Response.serverError().entity("UUID cannot be blank").build();
    }
    Entity entity = service.getById(uuid);
    if(entity == null) {
        return Response.status(Response.Status.NOT_FOUND).entity("Entity not found for UUID: " + uuid).build();
    }
    String json = //convert entity to json
    return Response.ok(json, MediaType.APPLICATION_JSON).build();
}

Response 클래스를 살펴보십시오 .

특히 여러 컨텐츠 유형을 전달하는 경우 항상 컨텐츠 유형을 지정해야하지만 모든 메시지가 JSON으로 표시되는 경우 메소드에 주석을 달 수 있습니다. @Produces("application/json")


12
작동하지만 Response 반환 값에 대해 마음에 들지 않는 점은 특히 코드를 사용하려는 클라이언트와 관련하여 코드를 오염 시킨다는 것입니다. 제 3 자에게 응답을 반환하는 인터페이스를 제공하면 실제로 어떤 유형을 반환하는지 알 수 없습니다. Spring은 주석으로보다 명확하게 해주므로 항상 상태 코드 (예 : HTTP 204)를 반환하는 경우 매우 유용합니다
Guido

19
이 클래스를 일반 (Response <T>)으로 만드는 것은 jax-rs에 대한 흥미로운 개선으로 두 대안의 장점을 모두 갖습니다.
귀도

41
어떻게 든 엔티티를 json으로 변환 할 필요가 없습니다. HTTP-Status 코드를 추가로 설정 return Response.status(Response.Status.Forbidden).entity(myPOJO).build();하면 마치 Works처럼 작업 할 수 있습니다 return myPOJO;.
kratenko

1
비즈니스 로직을 별도의 서비스 클래스로 분리하는 것이 효과적이라고 생각합니다. 엔드 포인트는 응답을 리턴 유형으로 사용하며 메소드는 주로 서비스 메소드에 대한 호출과 경로 및 매개 변수 주석입니다. 로직을 URL / 컨텐츠 유형 매핑 (고무가 도로에 부딪히는 지점)에서 깨끗하게 분리합니다.
Stijn de Witt

실제로 래핑되지 않은 객체를 응답으로 반환 할 수 있습니다.
ses

191

REST 웹 서비스에서 HTTP 상태 코드를 설정하는 몇 가지 유스 케이스가 있으며 기존 응답에 최소한 하나는 충분히 문서화되어 있지 않습니다 (예 : JAXB를 사용하여 자동 마법 JSON / XML 직렬화를 사용하는 경우) 직렬화 할 개체뿐만 아니라 기본 200과 다른 상태 코드).

서로 다른 사용 사례와 각 솔루션에 대한 솔루션을 시도하고 열거 해 보겠습니다.

1. 오류 코드 (500, 404, ...)

200 OK오류가 발생한 경우 와 다른 상태 코드를 반환하려는 경우 가장 일반적인 사용 사례 입니다.

예를 들면 다음과 같습니다.

  • 엔티티가 요청되었지만 존재하지 않습니다 (404)
  • 요청이 의미 상 올바르지 않습니다 (400)
  • 사용자에게 권한이 부여되지 않음 (401)
  • 데이터베이스 연결에 문제가 있습니다 (500).
  • 기타..

a) 예외를 던져라

이 경우 문제를 처리하는 가장 깨끗한 방법은 예외를 throw하는 것입니다. 이 예외는에 의해 처리되어 ExceptionMapper예외를 적절한 오류 코드가 포함 된 응답으로 변환합니다.

ExceptionMapperJersey로 사전 구성된 기본값 을 사용하고 (다른 구현과 동일하다고 생각합니다)의 기존 하위 클래스를 던질 수 javax.ws.rs.WebApplicationException있습니다. 이들은 서로 다른 오류 코드로 사전 맵핑되는 사전 정의 된 예외 유형입니다. 예를 들면 다음과 같습니다.

  • BadRequestException (400)
  • InternalServerErrorException (500)
  • NotFoundException (404)

기타 목록은 API 에서 찾을 수 있습니다.

또는 고유 한 사용자 정의 예외 및 ExceptionMapper클래스를 정의하고 @Provider어노테이션 ( 이 예제의 소스)을 통해 이러한 맵퍼를 Jersey에 추가 할 수 있습니다 .

public class MyApplicationException extends Exception implements Serializable
{
    private static final long serialVersionUID = 1L;
    public MyApplicationException() {
        super();
    }
    public MyApplicationException(String msg)   {
        super(msg);
    }
    public MyApplicationException(String msg, Exception e)  {
        super(msg, e);
    }
}

공급자 :

    @Provider
    public class MyApplicationExceptionHandler implements ExceptionMapper<MyApplicationException> 
    {
        @Override
        public Response toResponse(MyApplicationException exception) 
        {
            return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();  
        }
    }

참고 : 사용하는 기존 예외 유형에 대해 ExceptionMappers를 작성할 수도 있습니다.

b) 응답 빌더 사용

상태 코드를 설정하는 또 다른 방법은 Response빌더를 사용 하여 원하는 코드로 응답을 빌드하는 것입니다.

이 경우 메소드의 리턴 유형은이어야합니다 javax.ws.rs.core.Response. 이것은 hisdrewness의 승인 된 답변과 같은 다양한 다른 답변에 설명되어 있으며 다음과 같습니다.

@GET
@Path("myresource({id}")
public Response retrieveSomething(@PathParam("id") String id) {
    ...
    Entity entity = service.getById(uuid);
    if(entity == null) {
        return Response.status(Response.Status.NOT_FOUND).entity("Resource not found for ID: " + uuid).build();
    }
    ...
}

2. 성공, 그러나 200은 아님

반환 상태를 설정하려는 또 다른 경우는 작업이 성공했지만 본문에 반환하는 내용과 함께 200과 다른 성공 코드를 반환하려는 경우입니다.

빈번한 유스 케이스는 새 엔티티 ( POST요청) 를 작성 하고이 새 엔티티 또는 엔티티 자체에 대한 정보를 201 Created상태 코드 와 함께 리턴하려는 경우 입니다.

한 가지 방법은 위에서 설명한 것처럼 응답 객체를 사용하고 요청 본문을 직접 설정하는 것입니다. 그러나 이렇게하면 JAXB에서 제공하는 XML 또는 JSON으로 자동 직렬화 기능을 사용할 수 없게됩니다.

다음은 JAXB에 의해 JSON으로 직렬화 될 엔티티 객체를 리턴하는 원래 메소드입니다.

@Path("/")
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public User addUser(User user){
    User newuser = ... do something like DB insert ...
    return newuser;
}

새로 만든 사용자의 JSON 표현이 반환되지만 반환 상태는 201이 아니라 200입니다.

이제 문제는 Response빌더를 사용하여 리턴 코드를 설정 하려는 경우 Response메소드에서 오브젝트 를 리턴해야한다는 것입니다. User직렬화 할 개체를 계속 반환하려면 어떻게합니까 ?

a) 서블릿 응답에 코드를 설정하십시오.

이 문제를 해결하는 한 가지 방법은 가렛 윌슨의 답변에서 볼 수 있듯이 서블릿 요청 객체를 얻고 직접 응답 코드를 직접 설정하는 것입니다.

@Path("/")
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public User addUser(User user, @Context final HttpServletResponse response){

    User newUser = ...

    //set HTTP code to "201 Created"
    response.setStatus(HttpServletResponse.SC_CREATED);
    try {
        response.flushBuffer();
    }catch(Exception e){}

    return newUser;
}

이 메소드는 여전히 엔티티 오브젝트를 리턴하며 상태 코드는 201입니다.

작동하게하려면 응답을 플러시해야했습니다. 이것은 우리의 JAX_RS 리소스에서 저수준 서블릿 API 코드의 불쾌한 재생이며, 훨씬 더 나쁜 것은 헤더로 이미 헤더로 전송 되었기 때문에 헤더를 수정할 수 없게 만듭니다.

b) 개체와 함께 응답 개체 사용

이 경우 가장 좋은 솔루션은 Response 오브젝트를 사용하고이 응답 오브젝트에서 엔티티가 직렬화되도록 설정하는 것입니다. 이 경우 페이로드 엔터티의 유형을 나타 내기 위해 Response 객체를 일반으로 만드는 것이 좋지만 현재는 아닙니다.

@Path("/")
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response addUser(User user){

    User newUser = ...

    return Response.created(hateoas.buildLinkUri(newUser, "entity")).entity(restResponse).build();
}

이 경우 상태 코드를 201로 설정하기 위해 Response 빌더 클래스의 작성된 메소드를 사용합니다. entity () 메소드를 통해 엔티티 오브젝트 (사용자)를 응답에 전달합니다.

결과적으로 HTTP 코드는 원하는대로 401이며 응답 본문은 User 객체를 방금 반환했을 때와 똑같은 JSON입니다. 또한 위치 헤더를 추가합니다.

Response 클래스에는 다음과 같은 다양한 상태 (stati?)에 대한 여러 가지 빌더 메소드가 있습니다.

Response.accepted () Response.ok () Response.noContent () Response.notAcceptable ()

NB : hateoas 객체는 리소스 URI 생성을 돕기 위해 개발 한 도우미 클래스입니다. 여기서 자신의 메커니즘을 생각해 내야합니다.)

그게 다야.

이 긴 응답이 누군가에게 도움이되기를 바랍니다 :)


응답 대신 데이터 객체 자체를 반환하는 명확한 방법이 있는지 궁금합니다. 은 flush참 더럽습니다.
AlikElzin-kilaka

1
내 애완 동물의 말 : 401은 사용자 가 인증 되지 않았다는 것을 의미하지 않습니다 . 서버가 사용자를 모르기 때문에 클라이언트 가 인증되지 않았 음을 의미 합니다 . 기록 된 / 다른 방법으로 인식 된 사용자가 특정 작업을 수행 할 수없는 경우 올바른 응답 코드는 403 금지입니다.
Demonblack

69

hisdrewness의 대답은 효과가 있지만 Jackson + JAXB와 같은 공급자가 반환 된 객체를 JSON과 같은 출력 형식으로 자동 변환하도록 전체 접근 방식을 수정합니다. Apache CXF 게시물 (CXF 특정 클래스 사용)에서 영감을 얻어 JAX-RS 구현에서 작동 해야하는 응답 코드를 설정하는 한 가지 방법을 찾았습니다 .HttpServletResponse 컨텍스트를 삽입하고 수동으로 응답 코드를 설정하십시오. 예를 들어, CREATED적절한 경우 응답 코드를 설정하는 방법은 다음과 같습니다 .

@Path("/foos/{fooId}")
@PUT
@Consumes("application/json")
@Produces("application/json")
public Foo setFoo(@PathParam("fooID") final String fooID, final Foo foo, @Context final HttpServletResponse response)
{
  //TODO store foo in persistent storage
  if(itemDidNotExistBefore) //return 201 only if new object; TODO app-specific logic
  {
    response.setStatus(Response.Status.CREATED.getStatusCode());
  }
  return foo;  //TODO get latest foo from storage if needed
}

개선 : 다른 관련 답변을 찾은 후 HttpServletResponse싱글 톤 서비스 클래스 (적어도 RESTEasy)에 대해 멤버 변수로을 주입 할 수 있음을 알게 되었습니다! 이는 구현 세부 정보로 API를 오염시키는 것보다 훨씬 나은 접근 방법입니다. 다음과 같이 보일 것입니다 :

@Context  //injected response proxy supporting multiple threads
private HttpServletResponse response;

@Path("/foos/{fooId}")
@PUT
@Consumes("application/json")
@Produces("application/json")
public Foo setFoo(@PathParam("fooID") final String fooID, final Foo foo)
{
  //TODO store foo in persistent storage
  if(itemDidNotExistBefore) //return 201 only if new object; TODO app-specific logic
  {
    response.setStatus(Response.Status.CREATED.getStatusCode());
  }
  return foo;  //TODO get latest foo from storage if needed
}

실제로 접근 방식을 결합 할 수 있습니다 : 메소드에 주석을 달고 @Producesfinal에 미디어 유형을 지정하지 않으면 Response.ok반환 객체가 JAXB 직렬화되어 요청과 일치하는 적절한 미디어 유형으로 올바르게 반환됩니다. (방금 XML이나 JSON을 반환 할 수있는 단일 메서드로이 작업을 시도했습니다 @Produces. 주석을 제외하고는 메서드 자체를 언급 할 필요가 없습니다 .)
Royston Shufflebotham

당신은 맞습니다. 내 예는 콘텐츠 유형을 제공하는 것을 강조한 예입니다. 우리의 접근 방식은 비슷하지만 a MessageBodyWriterProvider사용하고 암시 적 내용 협상을 허용 한다는 아이디어는 있지만 예제에는 코드가 누락 된 것 같습니다. 여기에 제가 제공 한 또 다른 답변이 있습니다 : stackoverflow.com/questions/5161466/…
hisdrewness

8
의 상태 코드를 재정의 할 수 없습니다 response.setStatus(). 예를 들어 404 Not Found 응답 을 보내는 유일한 방법 은 응답 상태 코드를 설정 response.setStatus(404)한 다음 출력 스트림을 닫아 response.getOutputStream().close()JAX-RS가 내 상태를 재설정 할 수 없도록하는 것입니다.
Rob Juurlink

2
이 접근 방식을 사용하여 201 코드를 설정할 수 있었지만 response.flushBuffer()응답 코드를 재정의하는 프레임 워크를 피하기 위해 try-catch 블록을 추가 해야했습니다. 매우 깨끗하지 않습니다.
Pierre Henry

1
@RobJuurlink,을 구체적으로 반환 404 Not Found하려면 사용하는 것이 더 쉬울 수 있습니다 throw new NotFoundException().
Garret Wilson

34

리소스 계층을 Response객체를 깨끗하게 유지 @NameBinding하려면의 구현을 사용 하고 바인딩하는 것이 좋습니다 ContainerResponseFilter.

주석의 핵심은 다음과 같습니다.

package my.webservice.annotations.status;

import javax.ws.rs.NameBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Status {
  int CREATED = 201;
  int value();
}

필터의 고기는 다음과 같습니다.

package my.webservice.interceptors.status;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
public class StatusFilter implements ContainerResponseFilter {

  @Override
  public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException {
    if (containerResponseContext.getStatus() == 200) {
      for (Annotation annotation : containerResponseContext.getEntityAnnotations()) {
        if(annotation instanceof Status){
          containerResponseContext.setStatus(((Status) annotation).value());
          break;
        }
      }
    }
  }
}

그리고 리소스 구현은 단순히 다음과 같이됩니다.

package my.webservice.resources;

import my.webservice.annotations.status.StatusCreated;
import javax.ws.rs.*;

@Path("/my-resource-path")
public class MyResource{
  @POST
  @Status(Status.CREATED)
  public boolean create(){
    return true;
  }
}

API를 깨끗하고 정답으로 유지합니다. @Status (code = 205)와 같은 주석을 매개 변수화하고 인터셉터가 지정한 코드로 코드를 대체 할 수 있습니까? 기본적으로 필요할 때마다 코드를 재정의하는 주석을 제공한다고 생각합니다.
user2800708

@ user2800708, 이미 지역 코드에 대해이 작업을 수행했으며 제안한대로 답변을 업데이트했습니다.
Nthalk

감사합니다 이것과 몇 가지 방법으로 기본적으로 코드에서 REST API를 정리할 수 있으므로 REST에 대한 언급이없는 간단한 Java 인터페이스를 준수합니다. 또 다른 RMI 메커니즘입니다.
user2800708

6
StatusFilter에서 주석을 반복하는 대신 @ Provider 외에도 @ Status로 필터에 주석을 달 수 있습니다. 그런 다음 @ Status로 주석이 달린 리소스에서만 필터가 호출됩니다. 이것이 @ NameBinding
trevorism

1
좋은 설명 선 @trevorism. 주석 중 하나 그리 좋은 부작용이있다 StatusFilter으로는 @Status: 당신도 필요 주석의에 대한 기본 제공 value필드, 또는 클래스에 주석 할 때 하나를 선언 (예를 : @Status(200)). 이것은 분명히 이상적이지 않습니다.
Phil

6

예외로 인해 상태 코드를 변경하려는 경우 JAX-RS 2.0을 사용하면 이와 같은 ExceptionMapper를 구현할 수 있습니다. 이것은 전체 앱에 대해 이런 종류의 예외를 처리합니다.

@Provider
public class UnauthorizedExceptionMapper implements ExceptionMapper<EJBAccessException> {

    @Override
    public Response toResponse(EJBAccessException exception) {
        return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
    }

}

6

WS-RS에 오류가 발생하면 WebApplicationException을 사용하지 않는 이유는 무엇입니까?

@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Path("{id}")
public MyEntity getFoo(@PathParam("id") long id,  @QueryParam("lang")long idLanguage) {

if (idLanguage== 0){
    // No URL parameter idLanguage was sent
    ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
    builder.entity("Missing idLanguage parameter on request");
    Response response = builder.build();
    throw new WebApplicationException(response);
    }
... //other stuff to return my entity
return myEntity;
}

4
내 생각에 WebApplicationExceptions는 큰 스택 추적을 throw하기 때문에 클라이언트 측 오류에 적합하지 않습니다. 클라이언트 오류는 서버 측 스택 추적을 발생시키고 로깅을 오염시키지 않아야합니다.
Rob Juurlink

5

JAX-RS는 표준 / 사용자 정의 HTTP 코드를 지원합니다. 다음과 같은 ResponseBuilder 및 ResponseStatus를 참조하십시오.

http://jackson.codehaus.org/javadoc/jax-rs/1.0/javax/ws/rs/core/Response.ResponseBuilder.html#status%28javax.ws.rs.core.Response.Status%29

JSON 정보는 리소스 / 응용 프로그램과 관련된 데이터에 관한 것입니다. HTTP 코드는 요청중인 CRUD 작업의 상태에 대한 자세한 정보입니다. (적어도 그것이 RESTful 시스템에 있어야하는 방법입니다)


링크가 끊어졌습니다
Umpa

5

다음과 같이 반복되는 코드로 json 메시지를 작성하는 것이 매우 유용하다는 것을 알았습니다.

@POST
@Consumes("application/json")
@Produces("application/json")
public Response authUser(JsonObject authData) {
    String email = authData.getString("email");
    String password = authData.getString("password");
    JSONObject json = new JSONObject();
    if (email.equalsIgnoreCase(user.getEmail()) && password.equalsIgnoreCase(user.getPassword())) {
        json.put("status", "success");
        json.put("code", Response.Status.OK.getStatusCode());
        json.put("message", "User " + authData.getString("email") + " authenticated.");
        return Response.ok(json.toString()).build();
    } else {
        json.put("status", "error");
        json.put("code", Response.Status.NOT_FOUND.getStatusCode());
        json.put("message", "User " + authData.getString("email") + " not found.");
        return Response.status(Response.Status.NOT_FOUND).entity(json.toString()).build();
    }
}

4

여기 예제를보십시오. 최신 버전의 Jersey (2.3.1)에서 문제와 그 해결 방법을 가장 잘 보여줍니다.

https://jersey.java.net/documentation/latest/representations.html#d0e3586

기본적으로 사용자 정의 예외를 정의하고 리턴 유형을 엔티티로 유지합니다. 오류가 있으면 예외가 발생하고 그렇지 않으면 POJO를 반환합니다.


관심있는 예는 그들이 자신의 예외 클래스를 정의하고 그것을 구현하는 예라고 덧붙이고 싶습니다 Response. CustomNotFoundException수업을 찾아 게시물에 복사하면됩니다.
JBert

나는이 접근법을 오류에 사용하고 그것을 좋아한다. 그러나 '201 created'와 같은 성공 코드 (200과 다른)에는 적용되지 않습니다.
Pierre Henry

3

JAX-RS를 사용하지 않지만 비슷한 시나리오를 사용합니다.

response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());

Spring MVC를 사용하면 나에게 도움이되지만 쉽게 찾을 수있는 방법이 있습니다!
Caps

1

또한 기본적으로 Jersey는 http 코드 400 이상인 경우 응답 본문을 재정의합니다.

지정된 엔티티를 응답 본문으로 가져 오려면 web.xml 구성 파일에서 Jersey에 다음 init-param을 추가하십시오.

    <init-param>
        <!-- used to overwrite default 4xx state pages -->
        <param-name>jersey.config.server.response.setStatusOverSendError</param-name>
        <param-value>true</param-value>
    </init-param>

0

다음 코드는 저에게 효과적이었습니다. 주석이 달린 setter를 통해 messageContext를 주입하고 "add"메소드에서 상태 코드를 설정하십시오.

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

import org.apache.cxf.jaxrs.ext.MessageContext;

public class FlightReservationService {

    MessageContext messageContext;

    private final Map<Long, FlightReservation> flightReservations = new HashMap<>();

    @Context
    public void setMessageContext(MessageContext messageContext) {
        this.messageContext = messageContext;
    }

    @Override
    public Collection<FlightReservation> list() {
        return flightReservations.values();
    }

    @Path("/{id}")
    @Produces("application/json")
    @GET
    public FlightReservation get(Long id) {
        return flightReservations.get(id);
    }

    @Path("/")
    @Consumes("application/json")
    @Produces("application/json")
    @POST
    public void add(FlightReservation booking) {
        messageContext.getHttpServletResponse().setStatus(Response.Status.CREATED.getStatusCode());
        flightReservations.put(booking.getId(), booking);
    }

    @Path("/")
    @Consumes("application/json")
    @PUT
    public void update(FlightReservation booking) {
        flightReservations.remove(booking.getId());
        flightReservations.put(booking.getId(), booking);
    }

    @Path("/{id}")
    @DELETE
    public void remove(Long id) {
        flightReservations.remove(id);
    }
}

0

온 확장 응답Nthalk마이크로 프로파일 OpenAPI를하는 것은 당신이 사용하여 문서와 리턴 코드 정렬 할 수 있습니다 @APIResponse의 주석을.

이렇게하면 JAX-RS 메소드에 태그를 지정할 수 있습니다

@GET
@APIResponse(responseCode = "204")
public Resource getResource(ResourceRequest request) 

이 표준화 된 주석을 ContainerResponseFilter로 구문 분석 할 수 있습니다.

@Provider
public class StatusFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
        if (responseContext.getStatus() == 200) {
            for (final var annotation : responseContext.getEntityAnnotations()) {
                if (annotation instanceof APIResponse response) {
                    final var rawCode = response.responseCode();
                    final var statusCode = Integer.parseInt(rawCode);

                    responseContext.setStatus(statusCode);
                }
            }
        }
    }

}

메소드에 여러 주석을 넣을 때주의 사항

@APIResponse(responseCode = "201", description = "first use case")
@APIResponse(responseCode = "204", description = "because you can")
public Resource getResource(ResourceRequest request) 

-1

메시지 본문 독자 및 작성자와 함께 저지 2.0을 사용하고 있습니다. 메시지 본문 작성기의 구현에도 사용 된 특정 엔터티로 메서드 반환 유형을 사용했으며 동일한 pojo, SkuListDTO를 반환했습니다. @GET @Consumes ({ "application / xml", "application / json"}) @Produces ({ "application / xml", "application / json"}) @Path ( "/ skuResync")

public SkuResultListDTO getSkuData()
    ....
return SkuResultListDTO;

내가 바꾼 것은 이것뿐이었습니다. 작가 구현을 혼자 남겨두고 여전히 작동했습니다.

public Response getSkuData()
...
return Response.status(Response.Status.FORBIDDEN).entity(dfCoreResultListDTO).build();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.