java - Spring boot WAR部署无法在Tomcat中启动
问题描述
我试图将 Spring Boot 应用程序打包为战争。但是当我尝试在tomcat中部署war并尝试启动它时,它会抛出一个异常,说异常启动过滤器java.lang.AbstractMethodError。我的 Spring boot 版本是 2.2.6,Tomcat 版本是 8.5
08-May-2020 09:16:39.995 INFO [http-nio-8080-exec-27] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath
08-May-2020 09:16:48.472 INFO [http-nio-8080-exec-27] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
08-May-2020 09:17:04.638 SEVERE [http-nio-8080-exec-27] org.apache.catalina.core.StandardContext.filterStart Exception starting filter [APIAuthorizationFilter]
java.lang.AbstractMethodError
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:281)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:110)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4548)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5193)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.manager.ManagerServlet.start(ManagerServlet.java:1383)
at org.apache.catalina.manager.HTMLManagerServlet.start(HTMLManagerServlet.java:694)
at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:218)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:211)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:668)
at org.apache.catalina.valves.RequestFilterValve.process(RequestFilterValve.java:348)
at org.apache.catalina.valves.RemoteAddrValve.invoke(RemoteAddrValve.java:52)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1627)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
08-May-2020 09:17:04.646 INFO [http-nio-8080-exec-27] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
我的 APIAuthorizationFilter 类是
@Component
public class APIAuthorizationFilter implements Filter{
@Value("${hmac.secret.key}")
private String secretKey;
@Autowired
private UnauthorizedExceptionController exceptionController;
@Override
public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) sr;
HttpServletResponse httpServletResponse = (HttpServletResponse) sr1;
try {
MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest(httpServletRequest);
String authorizationHeader = HmacUtil.getHeaderValue(httpServletRequest, "Authorization");
String username = HmacUtil.getUsernameFromDecodeBasicAuth(authorizationHeader);
String password = HmacUtil.getPasswordFromDecodeBasicAuth(authorizationHeader);
String passwordSecretKey = secretKey;
if (passwordSecretKey != null && !passwordSecretKey.isEmpty() && passwordSecretKey.length() > 0) {
if (password.equals(passwordSecretKey.split(",")[0])) {
final SignatureBuilder signatureBuilder = new SignatureBuilder()
.algorithm(HmacUtil.getAlgorithm())
.accessUser(username)
.accessPassword(password)
.method(httpServletRequest.getMethod())
.contentType(MediaType.APPLICATION_JSON)
.resource(HmacUtil.getPath(httpServletRequest))
.apiSecret(AESEncryption.decryptText(passwordSecretKey.split(",")[1]).getBytes())
.body(HmacUtil.getRequestBody(multiReadRequest));
String hmac = HmacUtil.getHeaderValue(httpServletRequest, "auth");
Logger.getLogger(SignatureBuilder.class.getName()).log(Level.INFO, "Signature " + hmac);
if (!signatureBuilder.isHashEquals(hmac.getBytes())) {
throw new UnauthorizedException("Cannot access this resource");
}
fc.doFilter(multiReadRequest, sr1);
} else {
throw new UnauthorizedException("Cannot access this resource");
}
} else {
throw new UnauthorizedException("Cannot access this resource");
}
} catch (Exception e) {
Logger.getLogger(APIAuthorizationFilter.class.getName()).log(Level.SEVERE, "Exception:: " + e.getMessage(), e);
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
httpServletResponse.setContentType("application/json");
httpServletResponse.getWriter().write(exceptionController.unauthorizedStringRes(new UnauthorizedException("Cannot access this resource")));
}
}
我要注册的 FilterBean 类是
@Configuration
public class FilterBean {
@Bean
public FilterRegistrationBean registerFilter(APIAuthorizationFilter aPIAuthorizationFilter) {
FilterRegistrationBean<APIAuthorizationFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(aPIAuthorizationFilter);
filterRegistrationBean.addUrlPatterns("/api/*");
return filterRegistrationBean;
}
}
解决方案
在 tomcat 8 中部署时遇到同样的错误。尝试在 tomcat 9 中部署。我认为 spring boot 2.2 需要 tomcat 9。
Spring boot 2.2.6 的默认嵌入 tomcat 也是 org.apache.tomcat.embed 9.0.33
推荐阅读
- kotlin - 在 ktor 服务器中全局处理 http 异常是个好主意吗?
- javascript - Linebreak 不会被解释为 Node JS 中的换行符
- openvino - 无法从官方下载链接下载最新版本的openvino
- vue.js - 强制 Nuxt 运行脚本标签
- javascript - 在非 React 组件中使用钩子的替代方法是什么?
- python - 检查元组中的每个元素是否都是相同的类型
- android - 如何更改最近应用程序菜单中应用程序标题栏的颜色?
- qr-code - 为什么当我使用 QR Scanner 应用程序扫描 QR 码时,生成的 QR 看起来与打印的 QR 码不同?
- git - “git clone git://”和“git clone https://”有什么区别?
- mainframe - ISPF 重新连接成功但不显示 ISPF 主选项菜单