我在Spring Web Flow中启用基本验证时遇到了一些问题。
这就是我的webflow配置类的样子:
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();
}
}
我知道我必须在FlowBuilderServices
中设置验证器,但是当我这样做时,我会收到错误(运行webflow时):
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@6397b3b6 targetAction = [EvaluateAction@7880da33 expression = cartServiceImpl.validate(requestParameters.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)
这是该视图的代码:
<action-state id="addCartToOrder">
<evaluate expression="cartServiceImpl.validate(requestParameters.cartId)"
result="order.cart" />
一切正常,但只有从流注册表中删除addFlowBuilderServices
方法。你能给我任何指示如何正确配置吗?
我认为FlowBuilderServices
会覆盖某些流设置,因此无法正确解析表达式。
WebConfig.java
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 configureDefaultServletHandling (
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}*/
@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;
}
}