[英]Vaadin Spring Boot - There was an exception while trying to navigate to '' - NoSuchBeanDefinitionException
我正在使用 Vaadin 和 Spring Boot 來構建用作注冊表單的 webapp。
在 Tomcat 中部署 webapp 時遇到問題(但從 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 個后端服務 class 組成,用於與名為“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();
公共 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 -------------------------------------*/
還有我的服務 class:
@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;
}
通過對這個錯誤的一些研究,我將注釋 @Autowired 和 @Qualifier 添加到 OktaService 構造中,但沒有改變任何東西。
謝謝 !
一個潛在的問題可能與您的 Java package 結構有關。 Spring Boot does by default only look for annotated within the Java package (and it's children) that contains the Application
class.
如果您的OktaService
位於 package 結構的位置,則默認情況下不會找到它。 例如,如果您有com.example.myapp.ui
中的Application
和OktaService
中的com.example.myapp.service
,那么它將無法工作。 如果是這種情況,那么您可以更改 package 結構或在@SpringBootApplication
中設置scanBasePackages
屬性以定義覆蓋整個應用程序的位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.