微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vaadin Spring Boot - 尝试导航到 '' 时出现异常 - NoSuchBeanDefinitionException

如何解决Vaadin Spring Boot - 尝试导航到 '' 时出现异常 - NoSuchBeanDefinitionException

我正在使用 Vaadin 和 Spring Boot 构建用作注册表单的 webapp。

我在 Tomcat 中部署 web 应用程序时遇到问题(但从不直接从 Intellij IDE 启动时)。

堆栈跟踪是:

2021-06-04 09:27:13.289 ERROR  [reportException] com.vaadin.flow.router.InternalServerError:97 : There was an exception while trying to navigate to ''
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.project.widget.ui.views.register.RegisterView': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDeFinitionException: No qualifying bean of type 'com.project.widget.backend.services.OktaService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true),@org.springframework.beans.factory.annotation.Qualifier(value=OktaService)}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.autowireConstructor(AbstractAutowireCapablebeanfactory.java:1354) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBeanInstance(AbstractAutowireCapablebeanfactory.java:1204) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:314) ~[spring-beans-5.3.5.jar:5.3.5]
    at com.vaadin.flow.spring.SpringInstantiator.getorCreate(SpringInstantiator.java:117) ~[vaadin-spring-12.3.3.jar:?]
    at com.vaadin.flow.di.Instantiator.createRouteTarget(Instantiator.java:160) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.lambda$getRouteTarget$1(AbstractNavigationStateRenderer.java:137) ~[flow-server-2.5.3.jar:2.5.3]
    at java.util.Optional.orElseGet(Optional.java:267) ~[?:1.8.0_292]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.getRouteTarget(AbstractNavigationStateRenderer.java:136) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.sendBeforeEnterEventAndPopulateChain(AbstractNavigationStateRenderer.java:525) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.createChainIfEmptyAndExecuteBeforeEnterNavigation(AbstractNavigationStateRenderer.java:505) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.handle(AbstractNavigationStateRenderer.java:222) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.handleNavigation(Router.java:249) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.navigate(Router.java:220) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.navigate(Router.java:186) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.initializeUI(Router.java:93) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.BootstrapHandler.initializeUIWithRouter(BootstrapHandler.java:1532) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.BootstrapHandler.createAndInitUI(BootstrapHandler.java:1525) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.BootstrapHandler.synchronizedHandleRequest(BootstrapHandler.java:475) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1547) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:247) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:111) [vaadin-spring-12.3.3.jar:?]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) [servlet-api.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.apache.catalina.core.Applicationdispatcher.invoke(Applicationdispatcher.java:710) [catalina.jar:9.0.46]
    at org.apache.catalina.core.Applicationdispatcher.processRequest(Applicationdispatcher.java:457) [catalina.jar:9.0.46]
    at org.apache.catalina.core.Applicationdispatcher.doForward(Applicationdispatcher.java:352) [catalina.jar:9.0.46]
    at org.apache.catalina.core.Applicationdispatcher.forward(Applicationdispatcher.java:312) [catalina.jar:9.0.46]
    at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.dispatcherServlet.dodispatch(dispatcherServlet.java:1060) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.dispatcherServlet.doService(dispatcherServlet.java:962) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) [servlet-api.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) [servlet-api.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-websocket.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) [spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) [spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) [spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) [spring-boot-2.4.4.jar:2.4.4]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [catalina.jar:9.0.46]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [catalina.jar:9.0.46]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [catalina.jar:9.0.46]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [catalina.jar:9.0.46]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [catalina.jar:9.0.46]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) [tomcat-coyote.jar:9.0.46]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-coyote.jar:9.0.46]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-coyote.jar:9.0.46]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) [tomcat-coyote.jar:9.0.46]
    at org.apache.tomcat.util.net.socketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:9.0.46]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_292]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_292]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.46]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_292]
Caused by: org.springframework.beans.factory.NoSuchBeanDeFinitionException: No qualifying bean of type 'com.project.widget.backend.services.OktaService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true),@org.springframework.beans.factory.annotation.Qualifier(value=OktaService)}
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.raiseNoMatchingBeanFound(DefaultListablebeanfactory.java:1790) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.doResolveDependency(DefaultListablebeanfactory.java:1346) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.resolveDependency(DefaultListablebeanfactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar:5.3.5]
    ... 83 more

我的项目基本上由 2 个视图和 1 个后端服务类组成,用于与名为“Oktaservice”的远程 API 进行交互。

这是我的主视图的代码,导致在到达根页面时出现问题:

注册查看

@PWA(name = "Project",shortName = "Project",enableInstallPrompt = false)
@Route(value = "")
@PageTitle("Project")
@CssImport("./views/widget-view.css")
public class RegisterView extends Div {

    private final LanguageSettings languageSettings = new LanguageSettings();
    private final ResourceBundle bundle = ResourceBundle.getBundle(WidgetCaptions.class.getName(),languageSettings.getCurrentLanguage());

    private final OktaService oktaService;

    private final EmailField email = new EmailField();
    private final PasswordField password = new PasswordField();
    private final PasswordField confirmPassword = new PasswordField();
    private final GenderField gender;
    private final TextField firstName = new TextField();
    private final TextField lastName = new TextField();
    private final TextField company = new TextField();
    private final TextField street = new TextField();
    private final TextField zipCode = new TextField();
    private final TextField city = new TextField();
    private final CountryField country;
    private final TextField state = new TextField();
    private final CheckBox privacy_checkBox = new CheckBox();
    private final CheckBox conditions_checkBox = new CheckBox();

public RegisterView(@Autowired @Qualifier("OktaService") OktaService oktaService) { this.oktaService = oktaService; addClassName("注册视图");

        ///////////// For the country selector /////////////
        DefaultSchema schema = oktaService.getSchema();
        List<OneOfItem> items = schema.getDeFinitions().getCustom().getProperties().getCountry().getoneOf();

        HashMap<String,String> countries = new HashMap<>();
        List<String> values = new ArrayList<>();
        for (OneOfItem item : items) {
            String title = item.getTitle();
            String constant = item.getJsonMemberConst();

            countries.put(title,constant);
            values.add(title);
        }
        values.remove("-");
        country = new CountryField(bundle,values);
        ///////////////////////////////////////////////////
        gender = new GenderField(bundle);

        VerticalLayout page = new VerticalLayout();
        page.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
        page.addClassName("page");

        VerticalLayout signInLayout = new VerticalLayout();
        signInLayout.setHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
        signInLayout.addClassName("mainLayout");

        signInLayout.add(createTitle(),createDescription());

        HorizontalLayout error_layout = new HorizontalLayout();
        error_layout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
        error_layout.getStyle().set("display","none");
        error_layout.getStyle().set("color","#E55240");
        Icon error_icon = new Icon(VaadinIcon.INFO_CIRCLE);
        error_icon.setSize("15px");
        Span error_msg = new Span(bundle.getString("ErrorKey"));
        error_msg.getStyle().set("font-size","14px");
        error_msg.getStyle().set("margin-left","5px");
        error_layout.add(error_icon,error_msg);

        Button nextButton = new Button();
        nextButton.setText(bundle.getString("ContinueKey"));
        nextButton.getStyle().set("background","#44748A");
        nextButton.getStyle().set("color","white");
        nextButton.getStyle().set("cursor","pointer");
        nextButton.getStyle().set("margin-top","5px");

        nextButton.setWidthFull();

        signInLayout.add(createFormlayout(),conditionsCheck(),privacyCheck(),error_layout,nextButton,footerLayout());

        MainLayout mainLayout = new MainLayout(languageSettings);
        HorizontalLayout topBar = mainLayout.getTopBar();

        page.add(topBar,signInLayout);
        add(page);

        nextButton.addClickListener(e -> {
            if (checkFormValidation()) {
                createuser user = createuserProfile();
                if (!oktaService.createuser(user)) {
                    error_layout.getStyle().set("display","block");
                } else {
                    UI.getCurrent().navigate(ValidationView.class);
                }
            }
        });
    }   

    /*------------------------- design functions below -------------------------------------*/

还有我的服务类:

@Service("OktaService")
@PropertySource(value = {"classpath:application.properties"})
public class OktaService {

    private HttpHeaders headers;
    private HttpStatus status;
    private String oktaApiUrl;
    private static final String SCHEMAS_API = "/Meta/schemas/user/";

    private final Logger logger = LogManager.getLogger(OktaService.class);

    private RestClient rs;

    @Value("${okta.tenant}")
    private String oktaTenant;

    @Value("${okta.api.token}")
    private String oktaApiToken;

    @Value("${okta.custom.url}")
    private String oktaCustomUrl;

    public boolean createuser(createuser user) {
        rs = new RestClient(oktaTenant);
        rs.setApiToken(oktaApiToken);

        User userCreated = rs.postcreateuser(user,false);
        if (rs.getStatus() != null) {
            if (!rs.getStatus().toString().startsWith("4")) {
                logger.info("POST:createuser success : " + userCreated);
            } else {
                logger.error("POST:createuser Error creating user " + user.getProfile().getLogin());
                return false;
            }

            User userActivated = rs.postActivateUser(userCreated.getId(),true);
            if (!rs.getStatus().toString().startsWith("4")) {
                logger.info("POST:ActivateUser + sendEmail success : " + userCreated);
            } else {
                logger.error("POST:createuser Error creating user " + user.getProfile().getLogin());
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    public DefaultSchema getSchema() {
        RestTemplate rest = new RestTemplate();
        this.headers = new HttpHeaders();

        oktaApiUrl = "https://" + oktaTenant + "/api/v1";

        headers.add("Content-Type","application/json");
        headers.add("Accept","*/*");
        headers.add("Authorization","SSWS " + oktaApiToken);

        String url = oktaApiUrl + SCHEMAS_API + "default";
        httpentity<String> requestEntity = new httpentity<String>("",headers);
        ResponseEntity<DefaultSchema> responseEntity;

        try {
            responseEntity = rest.exchange(url,HttpMethod.GET,requestEntity,DefaultSchema.class);
            this.setStatus(responseEntity.getStatusCode());
            return responseEntity.getBody();
        } catch (HttpClientErrorException e) {
            logger.error(e.getStatusCode());
            return null;
        }
    }

    public String getoktaCustomUrl() {
        return oktaCustomUrl;
    }


    public void setStatus(HttpStatus status) {
        this.status = status;
    }

通过对这个错误的一些研究,我在 OktaService 构造中添加了 @Autowired 和 @Qualifier 注释,但没有改变任何东西。

谢谢!

解决方法

一个潜在的问题可能是您的 Java 包结构。默认情况下,Spring Boot 只会在包含 Application 类的 Java 包(及其子包)中查找注释。

如果您的 OktaService 位于包结构的某个位置,则默认情况下不会找到它。例如,如果您在 Application 中有 com.example.myapp.ui 而在 OktaService 中有 com.example.myapp.service,那么它将不起作用。如果是这种情况,那么您可以更改您的包结构或在 scanBasePackages 中设置 @SpringBootApplication 属性以定义一个覆盖整个应用程序的位置。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。