在Spring rest应用程序中,每个URL都必须以应用程序ID(appId)开头。必须在每个单独的休息服务中验证此appId。我尝试使用@Around建议创建一个@Aspect,而不是重复代码。这在任何休息方法之前都是正确执行的。
但是,如果应用程序ID未知,我既不想创建堆栈跟踪,也不希望既不返回200(响应OK)。相反,我确实想要返回一个BAD_REQUEST响应代码。
如果我在我的建议中抛出异常,我会得到堆栈跟踪而没有HTTP响应。如果我另一方面返回任何其他内容(但不要调用pjp.proceed),我会得到200的返回码。
有人可以帮助我将响应代码400返回给请求者吗?
到目前为止我的代码下方:
@Component
@Aspect
public class RequestMappingInterceptor {
@Autowired
ListOfValuesLookupUtil listOfValuesLookupUtil;
@Around("@annotation(requestMapping)")
public Object around(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {
Object[] arguments = pjp.getArgs();
if(arguments.length == 0 || !listOfValuesLookupUtil.isValidApplication(arguments[0].toString())) {
// toto : return bad request here ...
throw new BadRequestException("Application id unknown!");
} else {
return pjp.proceed();
}
}
}
答案 0 :(得分:1)
您可以尝试返回响应实体
if(arguments.length == 0 || !listOfValuesLookupUtil.isValidApplication(arguments[0].toString())) {
return new ResponseEntity<>("Application id unknown!", HttpStatus.BAD_REQUEST);
}else
答案 1 :(得分:1)
有多种处理方式。
一种方法是在控制器参数级别使用 required = true。
.. @RequestHeader(value = "something", required = true) final String something ..
参考:@RequestHeader required property behavior for request paramter and value
此外,您可以使用 ExceptionControllerAdvice 来处理 UnrecognizedPropertyException;您可以选择创建 Error 对象以获得更好的响应方法。
示例
@RestControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler(value = UnrecognizedPropertyException.class)
public ResponseEntity<Error> handle(@Nonnull final UnrecognizedPropertyException exception) {
final Error error = new Error();
error.setMessage(exception.getOriginalMessage());
error.setField(exception.getPropertyName());
error.setType(HttpStatus.BAD_REQUEST.name());
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
}
或者,如果你只想返回字符串
@ExceptionHandler(value = UnrecognizedPropertyException.class)
public ResponseEntity<String> handle(@Nonnull final UnrecognizedPropertyException exception) {
// If you don't want to use default message just use "Application Id Unknown!" instead of exception.getOriginalMessage()
return new ResponseEntity<>(exception.getOriginalMessage(), HttpStatus.BAD_REQUEST);
}
也可以在aspect的帮助下完成
@Component
@Aspect
public class RequestMappingInterceptor {
@Autowired
ListOfValuesLookupUtil listOfValuesLookupUtil;
@Around("@annotation(requestMapping)")
public Object around(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {
Object[] arguments = pjp.getArgs();
if(arguments.length == 0 || !listOfValuesLookupUtil.isValidApplication(arguments[0].toString())) {
// toto : return bad request here ...
throw new BadRequestException("Application id unknown!");
} else {
return pjp.proceed();
}
}
}
在这里,您需要在控制器或 ExceptionControllerAdvice 中处理 BadRequestExcption
@RestControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler(value = BadRequestExcption.class)
public ResponseEntity<Error> handle(@Nonnull final BadRequestExcption exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
}
}
答案 2 :(得分:0)
您可以尝试使用OncePerRequestFilter而不是Aspect。
创建过滤器类
public class URLFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
if(!request.getRequestURL().toString().contains("appId") {
response.setStatus(401);
return;
}
filterChain.doFilter(request, response);
}
在您的配置中为您的过滤器创建一个Spring bean(或使用@Component)
<bean id="urlFilter" class="com.xyz.filter.URLFilter" />
然后将过滤器添加到您的web.xml
<filter>
<filter-name>urlFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>urlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
警告:没有经过测试,你可以用更清洁的方式实现过滤器
答案 3 :(得分:0)
您需要访问HttpServletResponse
并使用它来发送错误代码。您可以通过RequestContextHolder
@Around("@annotation(requestMapping)")
public Object around(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {
Object[] arguments = pjp.getArgs();
if(arguments.length == 0 || !listOfValuesLookupUtil.isValidApplication(arguments[0].toString())) {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse());
response.sendError(HttpStatus.PRECONDITION_FAILED.value(), "Application Id Unknown!");
return null;
} else {
return pjp.proceed();
}
}
答案 4 :(得分:0)
我遇到了一个类似的问题,即暴露一个 Single 的 rest api。最后对我有用的是:
@Component
@Aspect
public class RequestMappingInterceptor {
@Around("@annotation(validRequest)")
public Object around(ProceedingJoinPoint pjp, ValidRequest validRequest) throws Throwable {
Object[] arguments = pjp.getArgs();
Boolean flag = validationMethod(arguments, validRequest);
return flag ? pjp.proceed() : Single.error(new BadRequestException("Value is invalid!"))
}
}