Spring类AbstractMessageConverterMethodProcessor

时间:2016-07-22 18:57:48

标签: java spring spring-mvc nullpointerexception

我正在创建一个我正在验证字段的服务。如果我的规则字段不正确,我抛出一个ResourceBusinessException,这是我为处理Unprocessable实体而创建的类。但是,抛出此异常时,Spring会在AbstractMessageConverterMethodProcessor类上抛出NullPointerException。

为了使我对我所谈论的内容更具可读性,下面我将附上与此问题相关的所有代码。为了使它更简单,我在代码上强制例外。

首先,我的春季版本:

<spring-framework-version>4.2.6.RELEASE</spring-framework-version>

我的控制器方法:

 /**
 * @param MyType
 * @return
 */
@ApiOperation(value = "", notes = "", authorizations = { @Authorization(value = ApplicationSwaggerConfig.securityOAuth2, scopes = { @AuthorizationScope(scope = WRITE_SCOPE, description = WRITE_DESCRIPTION) }) })
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 201, message = "Created"), @ApiResponse(code = 401, message = "Unauthorized"),
@ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 404, message = "Not Found"), @ApiResponse(code = 422, message = "Unprocessable Entity") })
@RequestMapping(value = "/xpto", method = POST, produces = { APPLICATION_XML_VALUE, APPLICATION_JSON_VALUE })
public ResponseEntity<Void> saveXPTO(@RequestBody MyType myType) {
    Long tenantId = 1L;
    MyClass myObject = service.findMyClass(tenantId, empresaType.getAttribute());
    MyOtherClass myOtherObject= this.applyForOne(myObject);
    PreconditionsRest.checkCondition(false, "ERROR!!"); // This is where I'm forcing an error.
    contribuinteService.saveMyOtherObject(myOtherObject);
    return new ResponseEntity<Void>(new HttpHeaders(), CREATED);
}

我的服务方式:

/**
 * Check condition.
 *
 * @param condition O(a)(s) condition
 */
public static void checkCondition(boolean condition, String message){
    if (!condition) {
        throw new ResourceBusinessException(message);
    }
}

我的ResourceBusinessException类:

public class ResourceBusinessException extends RuntimeException{

private static final long serialVersionUID = 1L;


private ErrorMessage errorMessage;


public ResourceBusinessException() {
    super();
}


public ResourceBusinessException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
}


public ResourceBusinessException(String message, Throwable cause) {
    super(message, cause);
}


public ResourceBusinessException(String message) {
    super(message);
}


public ResourceBusinessException(Throwable cause) {
    super(cause);
}


public ResourceBusinessException(ErrorMessage errorMessage){
    super(errorMessage.getDetail());
    this.errorMessage = errorMessage;
}


public ErrorMessage getErrorMessage() {
    return errorMessage;
}

}

我的ResourceBusinessExceptionHandler类:

public class ResourceBusinessExceptionHandler extends ErrorMessageRestExceptionHandler<ResourceBusinessException>{


private static final Logger LOGGER = LoggerFactory.getLogger(ResourceBusinessExceptionHandler.class);

private ErrorMessage errorMessage;

public ResourceBusinessExceptionHandler() {
    super(UNPROCESSABLE_ENTITY);
}


@Override
public ErrorMessage createBody(ResourceBusinessException ex, HttpServletRequest req) {
    LOGGER.debug("ResourceBusinessExceptionHandler - Started");
    ErrorMessage tmpl = super.createBody(ex, req);
    ValidationErrorMessage msg = new ValidationErrorMessage(tmpl);
    errorMessage=ex.getErrorMessage();
    if(errorMessage==null){
        errorMessage = new ErrorMessage();
    }
    msg.setType(ResourceHandlerUtil.getType(errorMessage,UNPROCESSABLE_ENTITY_SPEC));
    msg.setTitle(ResourceHandlerUtil.getTitle(errorMessage,HttpStatus.UNPROCESSABLE_ENTITY));
    msg.setDetail(ResourceHandlerUtil.getDetail(errorMessage,HttpStatus.UNPROCESSABLE_ENTITY));
    msg.setInstance(ResourceHandlerUtil.getUriInstance(errorMessage,UNPROCESSABLE_ENTITY_URI));
    LOGGER.debug("ResourceBusinessExceptionHandler - Complete");
    return msg;
}

我的配置bean:

<bean id="compositeExceptionResolver" class="org.springframework.web.servlet.handler.HandlerExceptionResolverComposite">
    <property name="order" value="0" />
    <property name="exceptionResolvers">
        <list>
            <ref bean="exceptionHandlerExceptionResolver" />
            <ref bean="restExceptionResolver" />
        </list>
    </property>
</bean>

    <bean id="restExceptionResolver" class="cz.jirutka.spring.exhandler.RestHandlerExceptionResolverFactoryBean">
    <property name="messageSource" ref="httpErrorMessageSource" />
    <property name="defaultContentType" value="application/json" />
    <property name="exceptionHandlers">
        <map>
            <!-- 422 -->
            <entry key="com.company.project.exception.ResourceBusinessException">
                <bean class="com.company.project.exception.handler.ResourceBusinessExceptionHandler"/>
            </entry>
        </map>
    </property>
</bean><bean id="exceptionHandlerExceptionResolver" class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"/>

<bean id="httpErrorMessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" p:defaultEncoding="UTF-8"/>

然后,当我向我的服务发出请求时,我的控制台上会出现以下堆栈跟踪:

  

15:26:09.119 [http-nio-8013-exec-3] DEBUG c.j.s.e.h.RestExceptionHandler - POST / api / xpto~&gt; 422   com.company.project.exception.ResourceBusinessException:ERROR !!

[...]然后,NullPointerException ...

  

错误c.j.s.e.RestHandlerExceptionResolver - 无法处理错误响应:&lt; 422 Unprocessable Entity,ValidationErrorMessage(errors = []),{}&gt;   java.lang.NullPointerException:null       在org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.getGenericType(AbstractMessageConverterMethodProcessor.java:271)〜[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:172)〜[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:183)〜[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       at cz.jirutka.spring.exhandler.RestHandlerExceptionResolver.processResponse(RestHandlerExceptionResolver.java:141)〜[spring-rest-exception-handler-1.0.3.jar:1.0.3]       at cz.jirutka.spring.exhandler.RestHandlerExceptionResolver.doResolveException(RestHandlerExceptionResolver.java:107)〜[spring-rest-exception-handler-1.0.3.jar:1.0.3]       at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:137)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1185)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1022)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:973)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在javax.servlet.http.HttpServlet.service(HttpServlet.java:648)[servlet-api.jar:na]       在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)[spring-webmvc-4.2.6.RELEASE.jar:4.2.6.RELEASE]       在javax.servlet.http.HttpServlet.service(HttpServlet.java:729)[servlet-api.jar:na]       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)[catalina.jar:8.0.36]       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)[catalina.jar:8.0.36]       at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)[tomcat-websocket.jar:8.0.36]       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)[catalina.jar:8.0.36]       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)[catalina.jar:8.0.36]       在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)[catalina.jar:8.0.36]       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)[catalina.jar:8.0.36]       at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)[catalina.jar:8.0.36]       在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)[catalina.jar:8.0.36]       在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)[catalina.jar:8.0.36]       at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)[catalina.jar:8.0.36]       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)[catalina.jar:8.0.36]       在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)[catalina.jar:8.0.36]       在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)[tomcat-coyote.jar:8.0.36]       at org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:670)[tomcat-coyote.jar:8.0.36]       在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1520)[tomcat-coyote.jar:8.0.36]       在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run(NioEndpoint.java:1476)[tomcat-coyote.jar:8.0.36]       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[na:1.8.0_65]       at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)[na:1.8.0_65]       at org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)[tomcat-util.jar:8.0.36]       在java.lang.Thread.run(Thread.java:745)[na:1.8.0_65]

更新

下面是类RestHanlderExceptionResolver的方法processResponse:

  protected void processResponse(ResponseEntity<?> entity, NativeWebRequest webRequest) throws Exception {

    ModelAndViewContainer mavContainer = new ModelAndViewContainer();
    try {
        responseProcessor.handleReturnValue(entity, null, mavContainer, webRequest);

    } catch (HttpMediaTypeNotAcceptableException ex) {
        LOG.debug("Requested media type is not supported, falling back to default one");
        fallbackResponseProcessor.handleReturnValue(entity, null, mavContainer, webRequest);
    }
}

1 个答案:

答案 0 :(得分:0)

我发现了问题。我使用Spring的版本与spring-rest-exception-handler-version不兼容。我正在使用的其余异常处理程序来自此github项目:https://github.com/jirutka/spring-rest-exception-handler

因此,如果您使用的是spring 4.2.6 RELEASE版本,则应将spring-rest-exception-handler的版本更新为1.2.0。这应该解决NullPointerException。