web-dev-qa-db-ja.com

spring @RestControllerでnullでHTTP 204を返します

Content-Length:0で200 OKを返します

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

}

単に、nullで204 No Contentを返すようにしたいのです。

Spring-mvc/restが200ではなくnullで204を返すように強制する方法はありますか? ResponseEntityなどを返すようにすべてのRESTメソッドを変更したくはありません。nullのみを204にマッピングします

21
user1606576

もちろんはい。

オプション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 ;
    }
}

タイプミスがあるかもしれませんが、コンセプトはわかります。

22
Karthik R

@ ResponseStatus アノテーションを使用できます。この方法では、voidメソッドを使用でき、ResponseEntityを構築する必要はありません。

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

BTWはオブジェクトが存在する場合に200を返し、そうでない場合はAPI REST design。に関して少し異常です。要求されたオブジェクトが見つからない場合に404​​(not found)を返すのが一般的です。 ControllerAdviceを使用して達成されます。

Springでは、REST=応答ステータスなどを決定するロジックを配置するよりも、例外ハンドラで例外を処理する方が適切です。これは@ControllerAdviceアノテーションを使用した例です。 http:/ /www.jcombat.com/spring/exception-handling-in-spring-restful-web-service

38
spekdrum

この問題はフィルターで解決しました。グローバルでシンプルです。

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

web.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>
9
mahieus

これを試すことができます:

@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);
       }
   }
}

UouはHttpStatus.BAD_REQUESTを204コードステータスに相当するものに変更する必要があります

4
Bilal BBB

同じ答えですが、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;
  }
}
1
Marek Raszewski