使用spring @RestController在null上返回HTTP 204

这将返回200 OK,Content-Length:0

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

简单地说,我希望它返回204 No Content on null。

有没有办法强制spring-mvc / rest在null而不是200时返回204? 我不想更改每个rest方法以返回ResponseEntity或类似的东西,只将null映射到204

当然是的。

选项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(HttpStatus.NO_CONTENT); } return object ; } } 

可能有拼写错误,但你得到的概念。

您可以使用@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设计上有点不寻常。 当找不到请求的对象时,返回404(未找到)是很常见的。 这可以使用ControllerAdvice来实现。

在Spring REST中,最好使用Exception处理程序处理Exceptions,而不是使用逻辑来决定响应状态等。这是使用@ControllerAdvice批注的示例: http : //www.jcombat.com/spring/exception-handling-在弹簧的RESTful的Web服务

我用filter解决了这个问题。 它是全球性的,简单的。

 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中添加以下内容

  restNoContentFilter your.package.filter.NoContentFilter   restNoContentFilter /rest/*  

你可以试试这个:

 @RestController public class RepoController { @RequestMapping(value = "/document/{id}", method = RequestMethod.GET) public ResponseEntity getDocument(@PathVariable long id) { if(noError) { ............ return new ResponseEntity(HttpStatus.OK); } else { return new ResponseEntity(HttpStatus.BAD_REQUEST); } } } 

您需要更改HttpStatus.BAD_REQUEST,使用等效的204代码状态

相同的答案,但由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 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; } }