2015-09-04 70 views
11

這將返回200 OK用的Content-Length:0返回HTTP 204的空彈簧@RestController

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

} 

簡單地說,我想它返回204上的空無內容。

有沒有辦法強制spring-mvc/rest在null上返回204而不是200?我不想改變每一個休息方法來返回ResponseEntity或類似的東西,只能映射到空間爲零

回答

15

當然是的。

選項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 ; 
    } 
} 

也許有錯別字,但你的概念。

+0

方案2爲我工作。好的解決方案 –

2

你可以試試這個:

@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代碼狀態

19

可以使用@ResponseStatus註解。這樣你可以有一個無效的方法,你不必建立一個ResponseEntity。

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

更新: 由於對此回覆的一些評論,我澄清了它。在Spring REST中,最好使用異常處理程序來處理異常,而不是通過邏輯來決定響應狀態等。這是一個使用@ControllerAdvice註釋的示例:http://www.jcombat.com/spring/exception-handling-in-spring-restful-web-service

因此,我認爲這是一個很好的解決方案。

+1

我認爲OP在成功時想要返回200,如果他沒有,則返回204。你可以在ResponseStatus中放入任何你想要的東西。但是這個想法是爲一個端點提供了多個可能的HTTP代碼。 –

+0

我同意@ Jean-FrançoisBeauchef。這不是正確的處理。無論結果如何(不包括異常情況),都會應用此響應狀態。提問者想知道如何迎合'null'的條件 –

+0

對不起,但我不同意。在使用Spring REST時,最好使用異常處理程序來處理異常和響應代碼。這是一個例子http://www.jcombat.com/spring/exception-handling-in-spring-restful-web-service – spekdrum

0

相同的答案,但通過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; 
    } 
} 
+0

你能提供更多關於這裏實際發生的細節嗎?我正在嘗試實施類似的解決方案。我的想法是自動返回204所有具有void返回類型的方法。看來這個解決方案需要該方法將HttpServletResponse作爲輸入。我想避免這種情況。 –

+0

嘗試使用靜態方式檢索HttpServletResponse,如[這裏](https://stackoverflow.com/questions/20531204/why-there-is-not-a-holder-class-for-response-like-requestcontextholder) 其餘的應該是相同的,但@Pointcut應該只覆蓋void方法。 –

8

我解決了這個問題,一個過濾器。這是全球性和簡單的。

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> 
+1

(HttpStatus.NO_CONTENT.value()) 我複製粘貼工作解決方案 +1票 –

+1

非常好的解決方案 – Stephan

相關問題