Crnk集成Spring Security仅GET请求可用,POST/DELETE报错
问题解决:Crnk 3.3+ 集成 Spring Boot 2.6.6 时 POST/DELETE 请求抛出 NoSuchMethodError
问题描述
使用Crnk 3.3+版本集成Spring Boot 2.6.6与Spring Security时,仅GET请求可正常工作,POST/DELETE请求会抛出java.lang.NoSuchMethodError,错误提示找不到io.crnk.spring.setup.boot.mvc.CrnkErrorController.getErrorAttributes(javax.servlet.http.HttpServletRequest, boolean)方法。
原因分析
Spring Boot 2.6.x对ErrorController相关的getErrorAttributes方法签名进行了变更,而Crnk 3.3版本的crnk-setup-spring-boot2模块未适配该变更。当POST/DELETE请求触发错误处理流程时,会调用该不存在的方法,导致异常;GET请求未触发该错误处理路径,因此可正常运行。
解决方案
方案1:升级Crnk到适配Spring Boot 2.6的版本
Crnk 3.4.0及以上版本已适配Spring Boot 2.6.x,修改依赖中的版本配置:
CRNK_VERSION = "3.4.0" implementation platform("io.crnk:crnk-bom:${CRNK_VERSION}") annotationProcessor platform("io.crnk:crnk-bom:${CRNK_VERSION}")
方案2:自定义CrnkErrorController覆盖默认实现
如果无法升级Crnk,可自定义CrnkErrorController修复方法签名,替换原有的bean:
import io.crnk.core.engine.error.ErrorResponse; import io.crnk.spring.setup.boot.mvc.CrnkErrorController; import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; @Component public class CustomCrnkErrorController extends CrnkErrorController { public CustomCrnkErrorController(ErrorAttributes errorAttributes) { super(errorAttributes); } @Override protected ErrorResponse errorToJsonApi(HttpServletRequest request, HttpServletResponse response) { WebRequest webRequest = new ServletWebRequest(request); Map<String, Object> errorAttributes = getErrorAttributes(webRequest, getErrorAttributeOptions(request, MediaType.ALL)); HttpStatus status = getStatus(request); return ErrorResponse.builder() .setStatus(status.value()) .setTitle((String) errorAttributes.get("error")) .setDetail((String) errorAttributes.get("message")) .build(); } // 适配Spring Boot 2.6+的方法签名 private Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { return super.getErrorAttributes(webRequest, options); } }
方案3:降级Spring Boot到Crnk 3.3支持的版本
将Spring Boot版本降级到2.5.x系列(Crnk 3.3官方支持的版本),同步调整Spring Security依赖版本:
implementation 'org.springframework.boot:spring-boot-starter-security:2.5.14'
验证
修改后重新启动应用,测试POST/DELETE请求,确认异常不再抛出,请求可正常执行。
内容的提问来源于stack exchange,提问作者emoleumassi
相关产品推荐
相关产品推荐

