我有一个请求映射 -
@RequestMapping("/fetchErrorMessages")
public @ResponseBody int fetchErrorMessages(@RequestParam("startTime") String startTime,@RequestParam("endTime") String endTime) throws Exception
{
if(SanityChecker.checkDateSanity(startTime)&&SanityChecker.checkDateSanity(endTime))
{
return 0;
}
else
{
throw new NotFoundException("Datetime is invalid");
}
}
如果startTime和endTime无效,我想抛出500错误但返回JSON中的异常字符串。但是,我得到一个HTML页面而不是说
Whitelabel错误页面
此应用程序没有/ error的显式映射,因此您将此视为后备。
Wed Dec 20 10:49:37 IST 2017
出现意外错误(type = Internal Server Error,status = 500) 日期时间无效
我想要用JSON
返回500{"error":"Date time format is invalid"}
我该怎么做?
答案 0 :(得分:6)
假设您有一个自定义的异常类NotFoundException
,其实现类似于:
public class NotFoundException extends Exception {
private int errorCode;
private String errorMessage;
public NotFoundException(Throwable throwable) {
super(throwable);
}
public NotFoundException(String msg, Throwable throwable) {
super(msg, throwable);
}
public NotFoundException(String msg) {
super(msg);
}
public NotFoundException(String message, int errorCode) {
super();
this.errorCode = errorCode;
this.errorMessage = message;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getErrorMessage() {
return errorMessage;
}
@Override
public String toString() {
return this.errorCode + " : " + this.getErrorMessage();
}
}
现在你想从控制器中抛出一些异常。如果抛出异常,则必须从标准的错误处理程序类中捕获它,例如在spring中,它们提供@ControllerAdvice
注释以应用于创建类标准错误处理程序。当它应用于类时,那么这个spring组件(我的意思是你注释的类)可以捕获从控制器抛出的任何异常。但我们需要用适当的方法映射异常类。因此,我们使用您的异常NotFoundException
处理程序定义了一个方法,如下所示。
@ControllerAdvice
public class RestErrorHandler {
@ExceptionHandler(NotFoundException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public Object processValidationError(NotFoundException ex) {
String result = ex.getErrorMessage();
System.out.println("###########"+result);
return ex;
}
}
您希望将 http状态发送到内部服务器错误(500),因此我们在这里使用了@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
。因为你使用了Spring-boot所以你不需要创建一个json字符串,除了一个简单的注释@ResponseBody
可以自动为你做。
答案 1 :(得分:4)
创建自定义例外。
public class SecurityException extends RuntimeException {
private static final long serialVersionUID = -7806029002430564887L;
private String message;
public SecurityException() {
}
public SecurityException(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
创建自定义响应实体。
public class SecurityResponse {
private String error;
public SecurityResponse() {
}
public SecurityResponse(String error) {
this.error = error;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
使用ExceptionHandler为自定义异常创建一个ControllerAdvice,它将处理自定义异常,填充并返回自定义响应,如下所示。
@ControllerAdvice
public class SecurityControllerAdvice {
@ExceptionHandler(SecurityException.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public SecurityResponse handleSecurityException(SecurityException se) {
SecurityResponse response = new SecurityResponse(se.getMessage());
return response;
}
}
根据您的情况抛出自定义异常。
throw new SecurityException("Date time format is invalid");
现在运行并测试你的应用程序。例如。 :
答案 2 :(得分:1)
这就是我在申请中的表现:
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class ExceptionHandlingControllerAdvice {
@ExceptionHandler(ExecutionRestrictionViolationException.class)
public ResponseEntity<String> handleExecutionRestrictionViolationException(ExecutionRestrictionViolationException ex) {
return response("Invalid Query", ex.getMessage(), HttpStatus.UNPROCESSABLE_ENTITY);
}
private static String createJson(String message, String reason) {
return "{\"error\" : \"" + message + "\"," +
"\"reason\" : \"" + reason + "\"}";
}
private static ResponseEntity<String> response(String message,
String reason,
HttpStatus httpStatus) {
String json = createJson(message, reason);
return new ResponseEntity<>(json, httpStatus);
}
}
说明:
你创建一个控制器建议,用一个特殊的注释标记它,并像任何其他bean一样定义(在我的例子中它是一个java配置,但它并不重要)
< / LI>对于您想要处理的每个异常 - 定义一个处理程序,它将以您想要的格式生成响应
现在这只是一种工作方式(它在最近的春季启动版本中可用) - 但还有其他方法:
我所知道的所有方法(甚至更多)都列在here。
答案 3 :(得分:1)
您可以使用NotFoundException
注释创建@ResponseStatus
课程,如下所示:
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class NotFoundException extends RuntimeException {
public NotFoundException() {
}
public NotFoundException(String message) {
super(message);
}
}
答案 4 :(得分:1)
Javax的接口名称为ExceptionMapper。请参阅下面的代码片段,对于应用程序中的每个RuntimeException,它都会将它映射到Json Response实体。
public class RuntimeExceptionMapper implements ExceptionMapper <RuntimeException> {
@Override
public Response toResponse(RuntimeException exception) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setMessage(exception.getMessage);
if (exception== null) {
logger.error("Exception Details Not found");
} else {
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(errorResponse )
.type(MediaType.APPLICATION_JSON)
.header("trace-id", "1234").build();
}
}
}
答案 5 :(得分:0)
Spring提供了一些方法来实现此目的,根据您的情况,一些方法比其他方法更明智。
(此处提供有关多个选项的出色教程。https://www.baeldung.com/spring-exceptions-json)
我最喜欢的是这个,因为我想发回适当的错误消息和适当的http响应,而无需在实用程序类中创建超类或创建辅助方法,也无需在任何地方复制样板。
如果您想通知调用者该事件导致了错误(并使用正确的JSON),请使用Spring的ResponseStatusException。它使您可以访问httpReponse对象,因此还可以发回“ ok”以外的其他响应。
它想要一个异常作为它的参数之一。对于我的一种情况,我想通知呼叫者他们正在尝试注册已经存在的用户。通常,查找用户不应引发异常,但是在这种情况下,我创建了自己的异常,然后将其以ResponseStatusException的形式扔回到调用方,如下所示:
@PostMapping("/register")
public ResponseEntity register(@RequestBody AccountUserDto user) {
UserDetails userExists = userDetailsService.loadUserByEmail(user.getEmail());
if (userExists != null) {
UserExistsException exc = new UserExistsException("Error: Email address " + user.getEmail() + " is already in use.");
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, "User Exists", exc);
}
....(fall through and create user)