[英]Vaadin Spring Boot - There was an exception while trying to navigate to '' - NoSuchBeanDefinitionException
I'm using Vaadin and Spring Boot to build webapp used as registration form.我正在使用 Vaadin 和 Spring Boot 来构建用作注册表单的 webapp。
I'm getting an issue when deploying the webapp inside a Tomcat (but never when lauching directly from Intellij IDE).在 Tomcat 中部署 webapp 时遇到问题(但从 Intellij IDE 直接启动时从来没有)。
The Stacktrace is:堆栈跟踪是:
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
My project is basically composed of 2 views and 1 backend service class used to interact with a remote API called "Oktaservice".我的项目基本上由 2 个视图和 1 个后端服务 class 组成,用于与名为“Oktaservice”的远程 API 交互。
Here is the code of my main view causing the issue when reaching the root page:这是到达根页面时导致问题的主要视图的代码:
RegisterView注册查看
@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;公共 RegisterView(@Autowired @Qualifier("OktaService") OktaService oktaService) { this.oktaService = oktaService; addClassName("register-view"); 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 -------------------------------------*/
And my Service class:还有我的服务 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;
}
With some research on this error I added the annotation @Autowired and @Qualifier to OktaService construction but did not change anything.通过对这个错误的一些研究,我将注释 @Autowired 和 @Qualifier 添加到 OktaService 构造中,但没有改变任何东西。
Thank you !谢谢 !
One potential problem could be with your Java package structure.一个潜在的问题可能与您的 Java package 结构有关。 Spring Boot does by default only look for annotated within the Java package (and it's children) that contains the Application
class. Spring Boot does by default only look for annotated within the Java package (and it's children) that contains the Application
class.
If your OktaService
is in a location of your package structure, then it won't be found by default.如果您的OktaService
位于 package 结构的位置,则默认情况下不会找到它。 As an example, if you have Application
in com.example.myapp.ui
and OktaService
in com.example.myapp.service
, then it won't work.例如,如果您有com.example.myapp.ui
中的Application
和OktaService
中的com.example.myapp.service
,那么它将无法工作。 If this is the case, then you can either change your package structure or set the scanBasePackages
property in @SpringBootApplication
to define a location that covers the entire application.如果是这种情况,那么您可以更改 package 结构或在@SpringBootApplication
中设置scanBasePackages
属性以定义覆盖整个应用程序的位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.