如何在春季启动中验证rest url



在春季启动中验证Rest URL。要求:如果我打错了URL,那么它应该抛出一个自定义异常。例如,正确的URL是"/fullment/600747l/send_to_hub"。如果我点击了"/api/600747l/send_to_hub_1",那么它应该返回如下异常"404:-找不到URL。".

现在它返回"500:-

{
"timestamp": 1531995246549,
"status": 500,
"error": "Internal Server Error",
"message": "Invalid Request URL.",
"path": "/api/600747l/send_to_hub_1"
}"

您需要编写带有注释@ControllerAdvice的NewClass,它将把所有异常重定向到此NewClass。示例

您的自定义异常类别:

@Data
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class IOApiException extends IOException {
private ErrorReason errorReason;
public IOApiException(String message, ErrorReason errorReason) {
super(message);
this.errorReason = errorReason;
}
}

现在是CustomExceptionHandler类-

@ControllerAdvice
@RestController
public class GlobalExceptionHandler {
Logger logger = LoggerFactory.getLogger(this.getClass());

@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(value = IOApiException.class)
public GlobalErrorResponse handleException(IOApiException e) {
logger.error("UNAUTHORIZED: ", e);
return new GlobalErrorResponse("URL Not Found", HttpStatus.UNAUTHORIZED.value(), e.getErrorReason());
}

//this to handle customErrorResponseClasses
public GlobalErrorResponse getErrorResponseFromGenericException(Exception ex) {
if (ex == null) {
return handleException(new Exception("INTERNAL_SERVER_ERROR"));
} 
else if (ex instanceof IOApiException) {
return handleException((IOApiException) ex);
}
}

现在您的错误响应类:

public class GlobalErrorResponse {
private String message;
@JsonIgnore
private int statusCode;
private ErrorReason reason;
}

错误原因类

public enum ErrorReason {
INTERNAL_SERVER_ERROR,
INVALID_REQUEST_PARAMETER,
INVALID_URL
}

添加并注册一个过滤器,该过滤器在类似的异常情况下调用GlobalExceptionHandler

public class ExceptionHandlerFilter implements Filter {
private final GlobalExceptionHandler globalExceptionHandler;
public ExceptionHandlerFilter(GlobalExceptionHandler globalExceptionHandler) {
this.globalExceptionHandler = globalExceptionHandler;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
} catch (Exception exception) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
GlobalErrorResponse errorResponse = globalExceptionHandler.getErrorResponseFromGenericException(exception);
httpResponse.setStatus(errorResponse.getStatusCode());
response.getWriter().write(new ObjectMapper().writeValueAsString(errorResponse));
}
}
@Override
public void destroy() {
}
}

像这样,您可以添加任意数量的异常。。并且可以手动处理。

根据您的问题,首先您需要定义一个基本url(例如-/api(,以便任何url都必须通过您的控制器进行处理。现在,在基本url之后,如/api/600747l/send_to_hub_1@PathVariable int id所示。这种情况很重要,因为Spring文档说,如果用@PathVariable注释的方法参数不能被强制转换为指定的类型(在我们的例子中是int(,它将被公开为String。因此,它可能会导致TypeMismatchException。

为了处理这个问题,我将在@Controller级别上使用@ExceptionHandler注释。这种方法非常适合这种情况。我只需要在控制器中进行2次更改:

1.添加MessageSource字段2.添加异常处理程序方法

@Autowired
private MessageSource messageSource;
...
@ExceptionHandler(TypeMismatchException.class)
@ResponseStatus(value=HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorInfo handleTypeMismatchException(HttpServletRequest req, TypeMismatchException ex) {
Locale locale = LocaleContextHolder.getLocale();
String errorMessage = messageSource.getMessage("error.bad.smartphone.id", null, locale);
errorMessage += ex.getValue();
String errorURL = req.getRequestURL().toString();
return new ErrorInfo(errorURL, errorMessage);
}
...

最新更新