NoSuchMethodError: org.springframework.boot.web.servlet.error.ErrorController.getErrorPath的解决方法

在使用zuul的过程中,启动应用程序,调用接口时报错:

java.lang.NoSuchMethodError: org.springframework.boot.web.servlet.error.ErrorController.getErrorPath()Ljava/lang/String;
	at org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping.lookupHandler(ZuulHandlerMapping.java:87) ~[spring-cloud-netflix-zuul-2.2.7.RELEASE.jar:2.2.7.RELEASE]
	at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.getHandlerInternal(AbstractUrlHandlerMapping.java:152) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:498) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1261) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1043) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.53.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.10.jar:5.3.10]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.53.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.53.jar:9.0.53]

找不到ErrorController中的getErrorPath()方法

在这里插入图片描述
在这里插入图片描述

由于作者使用的是最新的 spring-boot 2.5.5 版本,从 ErrorController 中删除了 getErrorPath() API,但spring-cloud-starter-netflix-zuul 2.2.7.RELEASE 仍然调用此 API 并导致此错误。

解决方法

方法一: 使用低版本spring boot兼容spring-cloud-starter-netflix-zuul

使用spring boot 2.4.8可以兼容spring-cloud-starter-netflix-zuul

补充:
spring-cloud 和 netflix-zuul 将在以下版本中正常工作:

spring-boot-starter-parent: 2.1.3.RELEASE
java.version: 1.8
spring-cloud.version: Greenwich.RELEASE
spring-cloud-starter-netflix-zuul: 2.1.0.RELEASE
spring-cloud-starter-netflix-eureka-client: 2.1.0.RELEASE
jackson-dataformat-xml: 2.9.9
spring-cloud-starter-netflix-eureka-server: 2.1.0.RELEASE

方法二: 创建BeanPostProcessor拦截 lookupHandler 方法的调用

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.cloud.netflix.zuul.web.ZuulController;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Fix for Zuul configuration with Spring Boot 2.5.x + Zuul - "NoSuchMethodError: ErrorController.getErrorPath()":
 */
@Configuration
public class ZuulConfiguration {
  /**
   * The path returned by ErrorController.getErrorPath() with Spring Boot < 2.5
   * (and no longer available on Spring Boot >= 2.5).
   */
  private static final String ERROR_PATH = "/error";
  private static final String METHOD = "lookupHandler";

  /**
   * Constructs a new bean post-processor for Zuul.
   *
   * @param routeLocator    the route locator.
   * @param zuulController  the Zuul controller.
   * @param errorController the error controller.
   * @return the new bean post-processor.
   */
  @Bean
  public ZuulPostProcessor zuulPostProcessor(@Autowired RouteLocator routeLocator,
                                             @Autowired ZuulController zuulController,
                                             @Autowired(required = false) ErrorController errorController) {
    return new ZuulPostProcessor(routeLocator, zuulController, errorController);
  }

  private enum LookupHandlerCallbackFilter implements CallbackFilter {
    INSTANCE;

    @Override
    public int accept(Method method) {
      if (METHOD.equals(method.getName())) {
        return 0;
      }
      return 1;
    }
  }

  private enum LookupHandlerMethodInterceptor implements MethodInterceptor {
    INSTANCE;

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
      if (ERROR_PATH.equals(args[0])) {
        // by entering this branch we avoid the ZuulHandlerMapping.lookupHandler method to trigger the 
        // NoSuchMethodError 
        return null;
      }
      return methodProxy.invokeSuper(target, args);
    }
  }

  private static final class ZuulPostProcessor implements BeanPostProcessor {

    private final RouteLocator routeLocator;
    private final ZuulController zuulController;
    private final boolean hasErrorController;

    ZuulPostProcessor(RouteLocator routeLocator, ZuulController zuulController, ErrorController errorController) {
      this.routeLocator = routeLocator;
      this.zuulController = zuulController;
      this.hasErrorController = (errorController != null);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      if (hasErrorController && (bean instanceof ZuulHandlerMapping)) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(ZuulHandlerMapping.class);
        enhancer.setCallbackFilter(LookupHandlerCallbackFilter.INSTANCE); // only for lookupHandler
        enhancer.setCallbacks(new Callback[] {LookupHandlerMethodInterceptor.INSTANCE, NoOp.INSTANCE});
        Constructor<?> ctor = ZuulHandlerMapping.class.getConstructors()[0];
        return enhancer.create(ctor.getParameterTypes(), new Object[] {routeLocator, zuulController});
      }
      return bean;
    }
  }
}

测试代码:

@RestController
@RequestMapping("/set")
public class TestController {

    @RequestMapping("/test")
    public String test(){
        return "hello world!";
    }
}

运行成功,不报错:
在这里插入图片描述

原文地址:https://stackoverflow.com/questions/68100671/nosuchmethoderror-org-springframework-boot-web-servlet-error-errorcontroller-ge
创作不易,关注、点赞就是对作者最大的鼓励,欢迎在下方评论留言
欢迎关注微信公众号:键指JAVA,定期分享Java知识,一起学习,共同成长。

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
### 回答1: 这是一个Java错误,具体是“java.lang.nosuchmethoderror: org.springframework.boot.web.servlet.error.errorcontroller.geterrorpath()ljava/lang/string;”。这个错误通常是由于Spring Boot应用程序中的版本不兼容或依赖项不正确引起的。建议检查应用程序的依赖项和版本,并确保它们与Spring Boot版本兼容。 ### 回答2: 这个错误通常是因为使用了不兼容版本的Spring Boot。通常,这个错误发生在当你在Spring Boot应用程序中定义一个错误控制器(ErrorController)时。在最新的Spring Boot版本中,getErrorPath()方法已经过时并被移除了,因此如果你使用了这个方法,就会出现NoSuchMethodError解决这个问题需要升级你的Spring Boot版本,以便使用新的getErrorAttributes()方法。 如果你已经升级了Spring Boot版本,但仍然出现这个错误,这可能是因为你的应用程序依赖的某个库也使用了旧版本的Spring Boot。在这种情况下,你需要使用mvn dependency:tree命令查找你的项目依赖,确认它们使用的Spring Boot版本是否一致。如果依赖库的版本较旧,你需要在pom.xml文件中修改它们的版本,或者使用Spring Boot的依赖管理功能(dependency management)来确保它们使用的是相同的Spring Boot版本。 另外,有时这个错误也可能是由于代码中使用了不太常见的组件或库导致的。在这种情况下,你需要仔细检查你的应用程序代码,查找是否有错误或不规范的使用Spring Boot的地方。如果找不到问题所在,你可以尝试使用调试工具来定位错误。 总之,Java.lang.NoSuchMethodError: org.springframework.boot.web.servlet.error.ErrorController.getErrorPath()Ljava/lang/String;的错误通常是由于Spring Boot版本不兼容或依赖库版本不一致引起的。要解决这个问题,你需要升级Spring Boot版本,确保依赖库使用相同的Spring Boot版本,或检查你的应用程序代码,找出错误的使用方式并进行调整。 ### 回答3: java.lang.nosuchmethoderror: org.springframework.boot.web.servlet.error.errorcontroller.geterrorpath()ljava/lang/string;是一种Java错误类型,通常出现在Spring Boot应用程序的Web模块中。该错误表明应用程序中缺少getErrorPath()方法的实现,该方法ErrorController接口的一部分,并用于处理应用程序中的错误请求。 通常,这种错误是由以下情况引起的: 1. 应用程序中使用的Spring Boot版本过低,可能与当前版本不兼容。这可能是因为getErrorPath()方法仅在较新的版本中才可用。 2. 应用程序的依赖关系存在错误,可能是由于通过Maven或Gradle构建时未能正确更新依赖项。 3. 当前应用程序尝试使用具有错误getErrorPath()实现的自定义ErrorController。 为了解决这个问题,你可以尝试执行以下任务: 1. 确认应用程序使用的Spring Boot版本是否正确,并更新到最新版本。 2. 检查应用程序的依赖项,确保所有依赖项都正确安装和更新。 3. 确认自定义ErrorController是否实现了getErrorPath()方法,并且已按正确方式定义。 4. 如果以上步骤都无效,你可以尝试升级应用程序中的所有依赖项,以确保您使用的所有库的最新版本都已安装。 最后,如果你遇到了一个极难解决的bug并且网搜索无法帮你解决问题,记得先把问题清楚的描述出来,以方便你快速获得解决之道,并尽可能引用相关错误日志。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.猫的树

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值