Spring-Java8 中的引导@ExceptionHandler 未伸出
Spring-boot @ExceptionHandler in Java8 is not reached out
我在 Java8 应用程序中使用 @ExcpetionHandler
。我无法联系到此功能。对于所有异常,HTTP 响应始终为 500(带有我插入到异常中的消息),并且它会忽略 @ExceptionHandler
方法。
当我的同事使用 java 7 编译器运行应用程序时,它可以运行。
@ExceptionHandler 注解无法通过 Java 8 到达的任何原因?
控制器:
validateInput()
正在投掷 InputParameterException
。 InputParameterException
被 try/catch 捕获,后者再次抛出它。
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import vce.exception.InputParameterException;
@Controller
@RestController
public class VRestController {
@Resource(name="aManager")
AManager aManager;
public void setAManager(AManager aManager) {
this.aManager = aManager;
}
@RequestMapping(value ="/authentication/signature", method = RequestMethod.PUT)
public ResponseEntity<Object> signature(@RequestBody final Signature signature) {
return handle(Marker.UseCases.SIGNATURE, new Supplier<Integer>() {
@Override
public Integer get() {
validateInput(signature);
aManager.doSomething(signature);
return 0;
}
});
}
private ResponseEntity<ErrorResponse> handle(UseCases useCase, Supplier<Integer> supplier) {
final Marker marker = Marker.REQUEST_MARKER.get();
marker.startUseCase().setUseCase(useCase.name()).setStartTime(DateTime.now());
try{
marker.setSerializationId(serializationID);
supplier.get();
}
catch (Exception e) {
marker.setException(e);
throw e;
}
finally {
......
}
return ResponseEntity.ok(new ErrorResponse(200,0,"Success"));
}
private static void validateInput(Signature signature) {
final String missingErr = "The request is missing the following parameter: ";
if(signature.getData()==null) {
throw new InputParameterException(missingErr+VConstants.DATA_FIELD_NAME, VErrorCodeEnum.MISSING_FIELD);
}
if(signature.getSignature()==null) {
throw new InputParameterException(missingErr+VConstants.SIGNATURE_FIELD_NAME, VErrorCodeEnum.MISSING_FIELD);
}
}
@ExceptionHandler(InputParameterException.class)
@ResponseStatus(value= HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handleInputParameterException(HttpServletRequest req, InputParameterException e) {
.....
return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getErrorCode().getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseStatus(value= HttpStatus.INTERNAL_SERVER_ERROR, reason="Internal Server Error - Any Exception")
public void handleAnyException(HttpServletRequest req, Exception e) {
.....
}
static class ErrorResponse {
public int statusCode;
public int errorCode;
public String message;
public ErrorResponse(int statusCode, int errorCode, String message) {
this.statusCode = statusCode;
this.errorCode = errorCode;
this.message = message;
}
}
}
来自pom.xml的相关部分:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.4.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependencies>
此代码无法通过 Java8 联系到 @ExceptionHandler
。当切换到 Java7 时,没有任何代码更改,它可以工作。
更新:
我收到的错误信息是:
{
"timestamp": 1494863566131,
"status": 500,
"error": "Internal Server Error",
"exception": "com.nds.ch.vge.vaus.exception.InputParameterException",
"message": "org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.nds.ch.vge.vaus.exception.InputParameterException: The request is missing the following parameter: data",
"path": "/authentication/signature"
}
我删除了 @Controller
注释,我也尝试使用解析器,但它没有用。
解析器的代码,与其余控制器在同一个包中 class:
@RestControllerAdvice
@EnableWebMvc
public class GlobalControllerExceptionHandler {
@ExceptionHandler(InputParameterException.class)
@ResponseStatus(value= HttpStatus.BAD_REQUEST)
public ErrorResponse handleInputParameterException(HttpServletRequest req, InputParameterException e) {
.....
return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getErrorCode().getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseStatus(value= HttpStatus.INTERNAL_SERVER_ERROR, reason="Internal Server Error - Any Exception")
public void handleAnyException(HttpServletRequest req, Exception e) {
.....
}
}
为了 Spring 启动以获取您的处理程序,您必须将其放在单独的 class 中并正确注释。
@RestControllerAdvice
@EnableWebMvc
public class GlobalControllerExceptionHandler {
@ExceptionHandler(value = { NoHandlerFoundException.class })
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiErrorResponse noHandlerFoundException(Exception ex) {
return new ApiErrorResponse(404, 4041, ex.getMessage());
}
}
另外,我认为用 @RestController
和 @Controller
注释您的控制器 class 也不是一个有效的选择。选择一个或另一个并相应地注释您的异常处理程序 class(@RestControllerAdvice
或 @ControllerAdvice
)
问题是导入错误 HttpServletRequest
class:
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
导入应该是:
import javax.servlet.http.HttpServletRequest;
当我更改导入时,@ExceptionHandler
方法起作用了。
我在 Java8 应用程序中使用 @ExcpetionHandler
。我无法联系到此功能。对于所有异常,HTTP 响应始终为 500(带有我插入到异常中的消息),并且它会忽略 @ExceptionHandler
方法。
当我的同事使用 java 7 编译器运行应用程序时,它可以运行。
@ExceptionHandler 注解无法通过 Java 8 到达的任何原因?
控制器:
validateInput()
正在投掷 InputParameterException
。 InputParameterException
被 try/catch 捕获,后者再次抛出它。
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import vce.exception.InputParameterException;
@Controller
@RestController
public class VRestController {
@Resource(name="aManager")
AManager aManager;
public void setAManager(AManager aManager) {
this.aManager = aManager;
}
@RequestMapping(value ="/authentication/signature", method = RequestMethod.PUT)
public ResponseEntity<Object> signature(@RequestBody final Signature signature) {
return handle(Marker.UseCases.SIGNATURE, new Supplier<Integer>() {
@Override
public Integer get() {
validateInput(signature);
aManager.doSomething(signature);
return 0;
}
});
}
private ResponseEntity<ErrorResponse> handle(UseCases useCase, Supplier<Integer> supplier) {
final Marker marker = Marker.REQUEST_MARKER.get();
marker.startUseCase().setUseCase(useCase.name()).setStartTime(DateTime.now());
try{
marker.setSerializationId(serializationID);
supplier.get();
}
catch (Exception e) {
marker.setException(e);
throw e;
}
finally {
......
}
return ResponseEntity.ok(new ErrorResponse(200,0,"Success"));
}
private static void validateInput(Signature signature) {
final String missingErr = "The request is missing the following parameter: ";
if(signature.getData()==null) {
throw new InputParameterException(missingErr+VConstants.DATA_FIELD_NAME, VErrorCodeEnum.MISSING_FIELD);
}
if(signature.getSignature()==null) {
throw new InputParameterException(missingErr+VConstants.SIGNATURE_FIELD_NAME, VErrorCodeEnum.MISSING_FIELD);
}
}
@ExceptionHandler(InputParameterException.class)
@ResponseStatus(value= HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handleInputParameterException(HttpServletRequest req, InputParameterException e) {
.....
return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getErrorCode().getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseStatus(value= HttpStatus.INTERNAL_SERVER_ERROR, reason="Internal Server Error - Any Exception")
public void handleAnyException(HttpServletRequest req, Exception e) {
.....
}
static class ErrorResponse {
public int statusCode;
public int errorCode;
public String message;
public ErrorResponse(int statusCode, int errorCode, String message) {
this.statusCode = statusCode;
this.errorCode = errorCode;
this.message = message;
}
}
}
来自pom.xml的相关部分:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.4.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependencies>
此代码无法通过 Java8 联系到 @ExceptionHandler
。当切换到 Java7 时,没有任何代码更改,它可以工作。
更新:
我收到的错误信息是:
{
"timestamp": 1494863566131,
"status": 500,
"error": "Internal Server Error",
"exception": "com.nds.ch.vge.vaus.exception.InputParameterException",
"message": "org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.nds.ch.vge.vaus.exception.InputParameterException: The request is missing the following parameter: data",
"path": "/authentication/signature"
}
我删除了 @Controller
注释,我也尝试使用解析器,但它没有用。
解析器的代码,与其余控制器在同一个包中 class:
@RestControllerAdvice
@EnableWebMvc
public class GlobalControllerExceptionHandler {
@ExceptionHandler(InputParameterException.class)
@ResponseStatus(value= HttpStatus.BAD_REQUEST)
public ErrorResponse handleInputParameterException(HttpServletRequest req, InputParameterException e) {
.....
return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), e.getErrorCode().getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseStatus(value= HttpStatus.INTERNAL_SERVER_ERROR, reason="Internal Server Error - Any Exception")
public void handleAnyException(HttpServletRequest req, Exception e) {
.....
}
}
为了 Spring 启动以获取您的处理程序,您必须将其放在单独的 class 中并正确注释。
@RestControllerAdvice
@EnableWebMvc
public class GlobalControllerExceptionHandler {
@ExceptionHandler(value = { NoHandlerFoundException.class })
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiErrorResponse noHandlerFoundException(Exception ex) {
return new ApiErrorResponse(404, 4041, ex.getMessage());
}
}
另外,我认为用 @RestController
和 @Controller
注释您的控制器 class 也不是一个有效的选择。选择一个或另一个并相应地注释您的异常处理程序 class(@RestControllerAdvice
或 @ControllerAdvice
)
问题是导入错误 HttpServletRequest
class:
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
导入应该是:
import javax.servlet.http.HttpServletRequest;
当我更改导入时,@ExceptionHandler
方法起作用了。