programing

스프링 @RestController를 사용하여 HTTP 204를 null로 반환합니다.

javajsp 2023. 9. 26. 22:00

스프링 @RestController를 사용하여 HTTP 204를 null로 반환합니다.

Content-Length: 0의 경우 200 OK를 반환합니다.

@RestController
public class RepoController {
    @RequestMapping(value = "/document/{id}", method = RequestMethod.GET)
    public Object getDocument(@PathVariable long id) {
       return null;
    }

}

간단히 말하면 204 No Content on null로 돌려주면 좋겠습니다.

스프링-mvc/rest를 null 200이 아닌 null에서 204를 반환하도록 강제하는 방법이 있습니까?ResponseEntity 같은 것을 반환하도록 모든 휴식 방법을 변경하지 않고 null을 204로 매핑합니다.

@ResponseStatus 주석을 사용할 수 있습니다.이렇게 하면 무효 메서드를 가질 수 있고 응답 엔터티를 구축할 필요가 없습니다.

@DeleteMapping(value = HERO_MAPPING)
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long heroId) {
    heroService.delete(heroId);
}

BTW는 오브젝트가 존재하면 200을 반환하고, 그 외에는 204를 반환하는 것은 API REST 디자인에 관해서는 조금 특이합니다.요청한 개체를 찾을 수 없을 때 404(찾지 않음)를 반환하는 것이 일반적입니다.그리고 이는 컨트롤러 조언을 사용하여 달성할 수 있습니다.

스프링 REST에서는 응답 상태 등을 결정하기 위해 논리를 넣는 대신 예외 처리기로 예외를 처리하는 것이 좋습니다.@ControllerAdvice 주석 http://www.jcombat.com/spring/exception-handling-in-spring-restful-web-service 을 사용한 예제입니다.

물론이지, 그렇습니다.

옵션 1:

@RestController
public class RepoController {
    @RequestMapping(value = "/document/{id}", method = RequestMethod.GET)
    public Object getDocument(@PathVariable long id, HttpServletResponse response) {
       Object object = getObject();
       if( null == object ){
          response.setStatus( HttpStatus.SC_NO_CONTENT);
       }
       return object ;
    }
}

옵션 2:

@RestController
public class RepoController {
    @RequestMapping(value = "/document/{id}", method = RequestMethod.GET)
    public Object getDocument(@PathVariable long id) {
       Object object = getObject();
       if ( null == object ){
          return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
       }

       return object ;
    }
}

오타가 날 수도 있지만 개념은 알 수 있습니다.

저는 필터로 이 문제를 해결했습니다.전 세계적이고 간단합니다.

package your.package.filter;

import org.springframework.http.HttpStatus;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class NoContentFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        filterChain.doFilter(httpServletRequest, httpServletResponse);
        if (httpServletResponse.getContentType() == null ||
                httpServletResponse.getContentType().equals("")) {
            httpServletResponse.setStatus(HttpStatus.NO_CONTENT.value());
        }
    }
}

웹.xml에 다음을 추가합니다.

<filter>
    <filter-name>restNoContentFilter</filter-name>
    <filter-class>your.package.filter.NoContentFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>restNoContentFilter</filter-name>
    <url-pattern>/rest/*</url-pattern>
</filter-mapping>

다음을 시도해 볼 수 있습니다.

@RestController
public class RepoController {

    @RequestMapping(value = "/document/{id}", method = RequestMethod.GET)
    public ResponseEntity<String> getDocument(@PathVariable long id) {

       if(noError) {
           ............
           return new ResponseEntity<String>(HttpStatus.OK); 
       }
       else {
           return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
       }
   }
}

HttpStatus를 변경해야 합니다.204 코드 상태에 해당하는 BAD_REQUEST

질문이 오래되었지만 전역 응답이 필요하고 Spring 4+가 있는 경우 컨트롤러 응답을 기반으로 응답 코드를 변경하는 ResponseBodyAdvice를 만들 수 있습니다.다음 예제는 모든 @RestController 클래스에 대해 수행합니다.

@ControllerAdvice(annotations = { RestController.class })
public class NullToNoContentResponseBodyAdvice
    implements ResponseBodyAdvice<Object>
{
    /**
     * {@inheritDoc}
     */
    @Override
    public Object beforeBodyWrite(final Object p_responseBodyObject, final MethodParameter p_methodParameter,
                                  final MediaType p_mediaType, final Class<? extends HttpMessageConverter<?>> p_class,
                                  final ServerHttpRequest p_serverHttpRequest,
                                  final ServerHttpResponse p_serverHttpResponse)
    {
        // ------------------------- DECLARE -------------------------- //

        if (p_responseBodyObject == null)
        {
            p_serverHttpResponse.setStatusCode(HttpStatus.NO_CONTENT);
        }

        // Always return object unchanged or it will break response
        return p_responseBodyObject;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean supports(final MethodParameter p_methodParameter, final Class<? extends HttpMessageConverter<?>> p_class)
    {
        return AbstractGenericHttpMessageConverter.class.isAssignableFrom(p_class);
    }
}

같은 답변이지만 AOP에서 해결:

@Aspect
public class NoContent204HandlerAspect {

  @Pointcut("execution(public * xx.xxxx.controllers.*.*(..))")
  private void anyControllerMethod() {
  }

  @Around("anyControllerMethod()")
  public Object handleException(ProceedingJoinPoint joinPoint) throws Throwable {

    Object[] args = joinPoint.getArgs();

    Optional<HttpServletResponse> response = Arrays.asList(args).stream().filter(x -> x instanceof HttpServletResponse).map(x -> (HttpServletResponse)x).findFirst();

    if (!response.isPresent())
      return joinPoint.proceed();

    Object retVal = joinPoint.proceed();
    if (retVal == null)
      response.get().setStatus(HttpStatus.NO_CONTENT.value());

    return retVal;
  }
}

맞춤 제작이 가능합니다.HttpMessageConverter이것을 지지하기 위해, 내가 이것을 하면서, 덧붙여 말했습니다.spring.http.converters.preferred-json-mapper=gson로.application.propertiesconfig 파일 및 다음과 같은 결과 조언:

@ControllerAdvice
public class CommonResultAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
    return true;
}

@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {

    if (null == o) {
    //set http code
        serverHttpResponse.setStatusCode(HttpStatus.NO_CONTENT);
        return BaseResult.success();
    }

    if (o instanceof String) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(BaseResult.success(o));
        } catch (JsonProcessingException ignore) {
        }
    }

    if (o instanceof BaseResult) {
        return o;
    }
    return BaseResult.success(o);
}

}

커스터마이즈 aHttpMessageConverter다음과 같이:

@Configuration
public class BeanConfiguration {
@Bean
public HttpMessageConverter resultToJsonConverter() {
    return new GsonHttpMessageConverter();
}
}

당신을 돕길 바랍니다.:)

언급URL : https://stackoverflow.com/questions/32396884/return-http-204-on-null-with-spring-restcontroller