Spring web flow can't resolve service bean?

匿名 (未验证) 提交于 2019-12-03 01:00:01

问题:

I have got following problem. I defined following service class

package godziszewski.patryk.ElectronicsStore.service.impl;  import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;  import godziszewski.patryk.ElectronicsStore.domain.Cart; import godziszewski.patryk.ElectronicsStore.domain.repository.CartRepository; import godziszewski.patryk.ElectronicsStore.exception.InvalidCartException; import godziszewski.patryk.ElectronicsStore.service.CartService;  @Service public class CartServiceImpl implements CartService {     @Autowired     CartRepository cartRepository;      public Cart create(Cart cart) {         return cartRepository.create(cart);     }      public Cart read(String cartId) {         return cartRepository.read(cartId);     }      public void update(String cartId, Cart cart) {         cartRepository.update(cartId, cart);     }      public void delete(String cartId) {         cartRepository.delete(cartId);     }      public Cart validate(String cartId) {         Cart cart = cartRepository.read(cartId);         if(cart==null || cart.getCartItems().size()==0) {         throw new InvalidCartException(cartId);         }         return cart;     } } 

Class is getting loaded by spring ( It's found by component scan and I can use it in other classes by autowiring) And I need to use this bean in spring web flow. My flow looks like this:

<var name="order" class="godziszewski.patryk.ElectronicsStore.domain.Order" />   <action-state id="addCartToOrder">     <evaluate expression="cartServiceImpl.validate(requestScope.cartId)"         result="order.cart" />     <transition to="InvalidCartWarning"         on-exception="godziszewski.patryk.ElectronicsStore.exception.InvalidCartException"/>     <transition to="loadCustomerAddress" /> </action-state> 

Everything should work, but somehow expression parser can't resolve my service bean. The error I'm getting:

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/ElectronicsStore] threw exception [Request processing failed; nested exception is org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing [AnnotatedAction@3d6c7f1e targetAction = [EvaluateAction@43e3c391 expression = cartServiceImpl.validate(requestScope.cartId), resultExpression = order.cart], attributes = map[[empty]]] in state 'addCartToOrder' of flow 'checkout' -- action execution attributes were 'map[[empty]]'] with root cause org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'cartServiceImpl' cannot be found on object of type 'org.springframework.webflow.engine.impl.RequestControlContextImpl' - maybe not public?     at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:224)     at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)     at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:81)     at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:51)     at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:87)     at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)     at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:299)     at org.springframework.binding.expression.spel.SpringELExpression.getValue(SpringELExpression.java:84)     at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:75)     at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)     at org.springframework.webflow.execution.AnnotatedAction.execute(AnnotatedAction.java:145)     at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)     at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:101)     at org.springframework.webflow.engine.State.enter(State.java:194)     at org.springframework.webflow.engine.Flow.start(Flow.java:527)     at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:368)     at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:223)     at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:140)     at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:263)     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)     at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)     at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:150)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:157)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)     at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)     at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)     at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)     at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)     at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)     at java.lang.Thread.run(Unknown Source) 

Full webflow config:

<?xml version="1.0" encoding="UTF-8"?> <flow xmlns="http://www.springframework.org/schema/webflow"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://www.springframework.org/schema/webflow    http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">      <var name="order" class="godziszewski.patryk.ElectronicsStore.domain.Order" />       <action-state id="addCartToOrder">         <evaluate expression="cartServiceImpl.validate(requestScope.cartId)"             result="order.cart" />         <transition to="InvalidCartWarning"             on-exception="godziszewski.patryk.ElectronicsStore.exception.InvalidCartException" />         <transition to="loadCustomerAddress" />     </action-state>          <action-state id="loadCustomerAddress">         <evaluate expression="customerServiceImpl.getCustomerByEmail(currentUser.name)"             result="order.customer" />             <transition to="customer"             on-exception="org.springframework.expression.spel.SpelEvaluationException"/>             <transition to="customer" />         </action-state>       <subflow-state id="customer" subflow="checkout/customer">       <input name="order" value="order"/>       <transition on="customerReady" to="orderConfirmation" />     </subflow-state>       <view-state id="orderConfirmation">         <transition on="orderConfirmed" to="processOrder" />         <transition on="backToCustomerInfo" to="customer" />     </view-state>      <action-state id="processOrder">         <evaluate expression="orderServiceImpl.saveOrder(order)" />         <transition to="thankCustomer" />     </action-state>      <view-state id="InvalidCartWarning">         <transition to="endState"/>     </view-state>      <view-state id="thankCustomer" model="order">         <transition to="endState"/>     </view-state>      <end-state id="endState"/>        <end-state id="cancelCheckout" view = "checkOutCancelled.jsp"/>           <global-transitions>         <transition on = "cancel" to="cancelCheckout" />     </global-transitions>  </flow> 

flow configuration:

package godziszewski.patryk.ElectronicsStore.config;  import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.validation.Validator; import org.springframework.webflow.config.AbstractFlowConfiguration; import org.springframework.webflow.definition.registry.FlowDefinitionRegistry; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; import org.springframework.webflow.executor.FlowExecutor; import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter; import org.springframework.webflow.mvc.servlet.FlowHandlerMapping;   public class FlowConfiguration extends AbstractFlowConfiguration {      @Autowired     Validator validator;     @Bean     public FlowDefinitionRegistry flowRegistry() {         return getFlowDefinitionRegistryBuilder()             .setBasePath("/WEB-INF/flows")             .setFlowBuilderServices(flowBuilderServices())             .addFlowLocationPattern("/**/*-flow.xml")             .build();     }     @Bean     public FlowExecutor flowExecutor() {         return getFlowExecutorBuilder(flowRegistry()).build();     }     @Bean     public FlowHandlerMapping flowHandlerMapping()     {         FlowHandlerMapping fh = new FlowHandlerMapping();         fh.setFlowRegistry(flowRegistry());         return fh;     }     @Bean     public FlowHandlerAdapter flowHandlerAdapter()     {         FlowHandlerAdapter fh = new FlowHandlerAdapter();         fh.setFlowExecutor(flowExecutor());         return fh;     }     @Bean     public FlowBuilderServices flowBuilderServices()     {         return getFlowBuilderServicesBuilder()                 .setValidator(validator)                 .build();     } } 

Also, rest of classes:

package godziszewski.patryk.ElectronicsStore.config;  import javax.servlet.FilterRegistration; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic;  import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;    public class ElectronicsStoreWebInitialiser extends AbstractAnnotationConfigDispatcherServletInitializer {     @Override     public void onStartup(ServletContext servletContext) throws ServletException {         super.onStartup(servletContext);         FilterRegistration.Dynamic encodingFilter = servletContext                 .addFilter("encoding-filter", new CharacterEncodingFilter());         encodingFilter.setInitParameter("encoding", "UTF-8");         encodingFilter.setInitParameter("forceEncoding", "true");         encodingFilter.addMappingForUrlPatterns(null, true, "/*");     }     @Override     protected Class<?>[] getRootConfigClasses() {         return new Class<?>[] { RootConfig.class };     }      @Override     protected Class<?>[] getServletConfigClasses() {         return new Class<?>[] { WebConfig.class };     }      @Override     protected String[] getServletMappings() {         return new String[] { "/" };     }      @Override     protected void customizeRegistration(Dynamic registration) {         registration.setMultipartConfig(                 new MultipartConfigElement("/tmp/images",                         2097152, 4194304, 0));     } } 

and class that imports flow config:

package godziszewski.patryk.ElectronicsStore.config;  import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.validation.Validator; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import org.springframework.web.servlet.view.tiles3.TilesViewResolver; import org.springframework.web.servlet.view.xml.MarshallingView; import org.springframework.web.util.UrlPathHelper; import godziszewski.patryk.ElectronicsStore.domain.Product;  @Configuration @Import(godziszewski.patryk.ElectronicsStore.config.FlowConfiguration.class) @EnableWebMvc @ComponentScan(basePackages = "godziszewski.patryk") public class WebConfig extends WebMvcConfigurerAdapter {     @Bean     public ViewResolver viewResolver() {     InternalResourceViewResolver resolver = new InternalResourceViewResolver();     resolver.setPrefix("/WEB-INF/views/");     resolver.setSuffix(".jsp");     resolver.setExposeContextBeansAsAttributes(true);      return resolver;     }       @Override         public void configurePathMatch(PathMatchConfigurer configurer) {              UrlPathHelper urlPathHelper = new UrlPathHelper();             urlPathHelper.setRemoveSemicolonContent(false);              configurer.setUrlPathHelper(urlPathHelper);         }       @Override     public Validator getValidator() {         return validator();     }      @Override     public void addResourceHandlers(final ResourceHandlerRegistry registry) {         registry.addResourceHandler("/resource/**").addResourceLocations("/resources/");     }     @Bean     TilesConfigurer tilesConfigurer() {         TilesConfigurer tiles = new TilesConfigurer();         tiles.setDefinitions(new String[] {                 "/WEB-INF/tiles/definition/tile-definition.xml"         });         tiles.setCheckRefresh(true);         return tiles;     }      @Bean     public ViewResolver tilesViewResolver() {         TilesViewResolver tv = new TilesViewResolver();         tv.setOrder(-2);         return  tv;     }     @Bean     public ResourceBundleMessageSource messageSource() {         ResourceBundleMessageSource rb = new ResourceBundleMessageSource();         rb.setBasename("messages");         return rb;     }     @Bean     public StandardServletMultipartResolver multipartResolver() {         return new StandardServletMultipartResolver();     }     @Bean     public ContentNegotiatingViewResolver contentResolver() {         ContentNegotiatingViewResolver cn = new ContentNegotiatingViewResolver();          List<View> listOfViews = new ArrayList<View>();         listOfViews.add(jsonView());         listOfViews.add(xmlView());          cn.setDefaultViews(listOfViews);          return cn;     }      @Bean     public MappingJackson2JsonView jsonView() {         MappingJackson2JsonView mj= new MappingJackson2JsonView();         mj.setPrettyPrint(true);         return mj;     }        @Bean     public MarshallingView xmlView() {         Jaxb2Marshaller ja = new Jaxb2Marshaller();         ja.setClassesToBeBound(Product.class);          MarshallingView mv = new MarshallingView(ja);          return mv;     }     @Bean     public Validator validator() {         LocalValidatorFactoryBean lv = new LocalValidatorFactoryBean();         lv.setValidationMessageSource(messageSource());         return lv;     } } 

Changed file

package godziszewski.patryk.ElectronicsStore.config;      import org.springframework.beans.factory.annotation.Autowired; import org.springframework.binding.convert.service.DefaultConversionService; import org.springframework.context.annotation.Bean; import org.springframework.validation.Validator; import org.springframework.webflow.config.AbstractFlowConfiguration; import org.springframework.webflow.definition.registry.FlowDefinitionRegistry; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; import org.springframework.webflow.executor.FlowExecutor; import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter; import org.springframework.webflow.mvc.servlet.FlowHandlerMapping;   public class FlowConfiguration extends AbstractFlowConfiguration {      @Autowired     Validator validator;     @Bean     public FlowDefinitionRegistry flowRegistry() {         return getFlowDefinitionRegistryBuilder(flowBuilderServices())                 //flow registry makes flow not recognize beans ?             //.setFlowBuilderServices(flowBuilderServices())             .setBasePath("/WEB-INF/flows")             .addFlowLocationPattern("/**/*-flow.xml")             .build();     }     @Bean     public FlowExecutor flowExecutor() {         return getFlowExecutorBuilder(flowRegistry()).build();     }     @Bean     public FlowHandlerMapping flowHandlerMapping()     {         FlowHandlerMapping fh = new FlowHandlerMapping();         fh.setFlowRegistry(flowRegistry());         return fh;     }     @Bean     public FlowHandlerAdapter flowHandlerAdapter()     {         FlowHandlerAdapter fh = new FlowHandlerAdapter();         fh.setFlowExecutor(flowExecutor());         return fh;     }     @Bean     public FlowBuilderServices flowBuilderServices()     {         return getFlowBuilderServicesBuilder()                 .setValidator(validator)                 .setDevelopmentMode(true)                 .setConversionService(conversionService())                 .build();     }     @Bean     public DefaultConversionService conversionService()     {         return new DefaultConversionService();     } } 

I'm adding github link to my repository, maybe you can find something wrong in there (about the flow) https://github.com/pgod/ElectronicsStore

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!