【问题标题】:Spring-boot @ExceptionHandler in Java8 is not reached outJava8 中的 Spring-boot @ExceptionHandler 未达到
【发布时间】:2017-05-15 06:46:57
【问题描述】:

我在我的 Java8 应用程序中使用 @ExcpetionHandler。我无法使用此功能。在所有异常情况下,HTTP 响应始终为 500(我在异常中插入了消息),并且它忽略了 @ExceptionHandler 方法。

当我的同事使用 java 7 编译器运行应用程序时,它可以工作。

Java 8 无法访问 @ExceptionHandler 注释的任何原因?

控制器:

validateInput() 正在抛出 InputParameterExceptionInputParameterException 被 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注解,我也尝试使用解析器,但是没有用。

解析器的代码,与其余控制器类在同一个包中:

@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) {

            .....
        }
}

【问题讨论】:

  • 为什么你有Controller和RestController?您是否尝试过将 exceptionHandlers 放在它自己的 Component 类中?
  • @Shervin Asgari,我想让 ExceptionHandler 在控制器中。我只有 1 个控制器,不需要使用不同的类。
  • 当你有 500 个时看到的实际错误是什么?
  • 代码看起来是正确的,除了多余的@Controller@ResponeBody。也许问题是在构建阶段?在使用 Java8 构建之前尝试 mvn clean
  • @Eugene - 是的,500

标签: java spring-boot java-8 exceptionhandler


【解决方案1】:

要让 Spring Boot 拾取您的处理程序,您必须将它放在一个单独的类中并正确注释它。

@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 注释控制器类也不是一个有效的选项。选择一个或另一个并相应地注释您的异常处理程序类(@RestControllerAdvice@ControllerAdvice)

【讨论】:

  • 我试过你的建议 - 没用。我更新了我的帖子。
  • 请将此添加到您的 application.properties:spring.mvc.throw-exception-if-no-handler-found=true
【解决方案2】:

问题是导入错误的HttpServletRequest 类:

import org.apache.catalina.servlet4preview.http.HttpServletRequest;

导入应该是:

import javax.servlet.http.HttpServletRequest;

当我更改导入时,@ExceptionHandler 方法起作用了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-09
    • 2018-06-16
    • 1970-01-01
    • 2021-08-27
    • 2020-06-02
    • 2012-10-27
    • 2021-12-24
    • 2017-12-30
    相关资源
    最近更新 更多