Spring Boot 带有自定义验证程序和本机可执行文件的Sping Boot 3

jecbmhm3  于 2022-12-04  发布在  Spring
关注(0)|答案(1)|浏览(119)

您好,Sping Boot Maven,
我正在尝试创建一个注解自定义验证,当我在JVM模式下执行时,一切都按预期工作,但当我作为本机映像执行时,我收到此错误

堆栈跟踪

2022-11-28T17:09:40.312+01:00 ERROR 14056 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'info.novatec.validator.api.validators.ClaimNumberValidator': Failed to instantiate [info.novatec.validator.api.validators.ClaimNumberValidator]: No default constructor found] with root cause

java.lang.NoSuchMethodException: info.novatec.validator.api.validators.ClaimNumberValidator.<init>()
        at java.base@17.0.5/java.lang.Class.getConstructor0(DynamicHub.java:3585) ~[CustomValidatorExample:na]
        at java.base@17.0.5/java.lang.Class.getDeclaredConstructor(DynamicHub.java:2754) ~[CustomValidatorExample:na]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:79) ~[CustomValidatorExample:6.0.2]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1300) ~[CustomValidatorExample:6.0.2]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1198) ~[CustomValidatorExample:6.0.2]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[CustomValidatorExample:6.0.2]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[CustomValidatorExample:6.0.2]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:321) ~[CustomValidatorExample:6.0.2]
        at org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory.getInstance(SpringConstraintValidatorFactory.java:56) ~[na:na]
        at org.hibernate.validator.internal.engine.constraintvalidation.ClassBasedValidatorDescriptor.newInstance(ClassBasedValidatorDescriptor.java:84) ~[na:na]
        at org.hibernate.validator.internal.engine.constraintvalidation.AbstractConstraintValidatorManagerImpl.createAndInitializeValidator(AbstractConstraintValidatorManagerImpl.java:89) ~[CustomValidatorExample:8.0.0.Final]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManagerImpl.getInitializedValidator(ConstraintValidatorManagerImpl.java:117) ~[na:na]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:136) ~[CustomValidatorExample:8.0.0.Final]
        at org.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints(SimpleConstraintTree.java:58) ~[na:na]
        at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:75) ~[CustomValidatorExample:8.0.0.Final]
        at org.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(MetaConstraint.java:130) ~[CustomValidatorExample:8.0.0.Final]
        at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:123) ~[CustomValidatorExample:8.0.0.Final]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:555) ~[na:na]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraints(ValidatorImpl.java:537) ~[na:na]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateParametersForSingleGroup(ValidatorImpl.java:991) ~[na:na]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateParametersForGroup(ValidatorImpl.java:932) ~[na:na]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateParametersInContext(ValidatorImpl.java:863) ~[na:na]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:283) ~[na:na]
        at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:235) ~[na:na]
        at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:121) ~[na:na]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[CustomValidatorExample:6.0.2]
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:752) ~[na:na]
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703) ~[na:na]
        at info.novatec.validator.api.ClaimNumberController$$SpringCGLIB$$0.isClaimNumberValid(<generated>) ~[CustomValidatorExample:na]
        at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:568) ~[CustomValidatorExample:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1003) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:895) ~[CustomValidatorExample:6.0.2]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:705) ~[CustomValidatorExample:6.0]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:880) ~[CustomValidatorExample:6.0.2]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[CustomValidatorExample:6.0]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[CustomValidatorExample:10.1.1]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[CustomValidatorExample:6.0.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[CustomValidatorExample:6.0.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[CustomValidatorExample:6.0.2]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[CustomValidatorExample:6.0.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[na:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[na:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[na:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[na:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[CustomValidatorExample:10.1.1]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[na:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[CustomValidatorExample:10.1.1]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[na:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[na:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[na:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[CustomValidatorExample:10.1.1]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[na:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739) ~[na:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[CustomValidatorExample:10.1.1]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[na:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[na:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[na:na]
        at java.base@17.0.5/java.lang.Thread.run(Thread.java:833) ~[CustomValidatorExample:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:775) ~[CustomValidatorExample:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:203) ~[na:na]

我的验证器

import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator
import jakarta.validation.ConstraintValidatorContext
import jakarta.validation.Payload
import kotlin.annotation.AnnotationTarget.VALUE_PARAMETER
import kotlin.reflect.KClass

@Target(VALUE_PARAMETER)
@MustBeDocumented
@Constraint(validatedBy = [ClaimNumberValidator::class])
annotation class ClaimNumber(
    val message: String = "ClaimNumber must 11 chars long and start with 'KR'",
    val groups: Array<KClass<*>> = [],
    val payload: Array<KClass<out Payload>> = []
)

class ClaimNumberValidator: ConstraintValidator<ClaimNumber, String> {
    override fun isValid(value: String?, context: ConstraintValidatorContext?): Boolean {
        return value!=null && value.trim().length == 11 && value.trim().startsWith("KR")
    }
}

我的控制器

@RestController
@RequestMapping("/claimNumber")
@Validated
class ClaimNumberController {

    @GetMapping("/{claimNumber}/isValid")
    fun isClaimNumberValid(
            @PathVariable
            @ClaimNumber
            claimNumber: String
    ): Boolean {
        return true
    }
}

完整示例如下:CustomValidatorExample
我在spring-native项目中发现了这个bug 1570(它现在被spring Boot 3作为超级种子)。
我的问题是:

  • 我是否也应该在Spring Boot 3中提交错误报告?
  • 我可以使用TypeHints让它工作吗?如果可以,如何做?
68bkxrlz

68bkxrlz1#

这是will be addressed in Spring Framework。同时,您可以注册其他反映提示来解决这个问题:

package info.novatec.validator

import info.novatec.validator.api.validators.ClaimNumberValidator
import org.springframework.aot.hint.MemberCategory
import org.springframework.aot.hint.RuntimeHints
import org.springframework.aot.hint.RuntimeHintsRegistrar
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.ImportRuntimeHints

@ImportRuntimeHints(ClaimNumberValidatorRuntimeHints::class)
@SpringBootApplication
class CustomValidatorExampleApplication

fun main(args: Array<String>) {
    runApplication<CustomValidatorExampleApplication>(*args)
}

class ClaimNumberValidatorRuntimeHints : RuntimeHintsRegistrar {
    override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
        hints.reflection().registerType(ClaimNumberValidator::class.java, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)
    }
}

相关问题