Vaadin Spring 引导 - 尝试导航到“”时出现异常 - NoSuchBeanDefinitionException
Vaadin Spring Boot - There was an exception while trying to navigate to '' - NoSuchBeanDefinitionException
我正在使用 Vaadin 和 Spring Boot 来构建用作注册表单的 webapp。
我在 Tomcat 中部署 webapp 时遇到问题(但从 Intellij IDE 直接启动时从来没有)。
Stacktrace 是:
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(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[=11=]0(ErrorPageFilter.java:64) [spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.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();
public RegisterView(@Autowired @Qualifier("OktaService") OktaService oktaService) {
this.oktaService = okta服务;
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;
}
通过对这个错误的一些研究,我在 OktaService 构造中添加了注释 @Autowired 和 @Qualifier 但没有改变任何东西。
谢谢!
一个潜在的问题可能与您的 Java 包结构有关。 Spring 默认情况下,Boot 仅在包含 Application
class.
的 Java 包(及其子包)中查找注释
如果您的 OktaService
位于包结构的某个位置,则默认情况下不会找到它。例如,如果您在 com.example.myapp.ui
中有 Application
,在 com.example.myapp.service
中有 OktaService
,那么它将不起作用。如果是这种情况,那么您可以更改包结构或在 @SpringBootApplication
中设置 scanBasePackages
属性 以定义覆盖整个应用程序的位置。
我正在使用 Vaadin 和 Spring Boot 来构建用作注册表单的 webapp。
我在 Tomcat 中部署 webapp 时遇到问题(但从 Intellij IDE 直接启动时从来没有)。
Stacktrace 是:
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(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[=11=]0(ErrorPageFilter.java:64) [spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.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();
public RegisterView(@Autowired @Qualifier("OktaService") OktaService oktaService) { this.oktaService = okta服务; 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;
}
通过对这个错误的一些研究,我在 OktaService 构造中添加了注释 @Autowired 和 @Qualifier 但没有改变任何东西。
谢谢!
一个潜在的问题可能与您的 Java 包结构有关。 Spring 默认情况下,Boot 仅在包含 Application
class.
如果您的 OktaService
位于包结构的某个位置,则默认情况下不会找到它。例如,如果您在 com.example.myapp.ui
中有 Application
,在 com.example.myapp.service
中有 OktaService
,那么它将不起作用。如果是这种情况,那么您可以更改包结构或在 @SpringBootApplication
中设置 scanBasePackages
属性 以定义覆盖整个应用程序的位置。