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にマッピングします
もちろんはい。
オプション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 ;
}
}
タイプミスがあるかもしれませんが、コンセプトはわかります。
@ 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
この問題はフィルターで解決しました。グローバルでシンプルです。
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>
これを試すことができます:
@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コードステータスに相当するものに変更する必要があります
同じ答えですが、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;
}
}