2017-09-13 143 views
6

环境:春季启动JSF集成

Tomcat的8

春季启动1.5

JSF 2.2

的Apache MyFaces的

Spring MVC的

代码:

我在Servlet 3.0环境中集成了Spring Boot和JSF 2.2。

配置类:

JSFConfig.java - 配置为JSF。

@Configuration 
@ComponentScan({"com.atul.jsf"}) 
public class JSFConfig { 

     @Bean 
     public ServletRegistrationBean servletRegistrationBean() { 
      FacesServlet servlet = new FacesServlet(); 
      return new ServletRegistrationBean(servlet, "*.jsf"); 
     } 

} 

春季启动主类:

@SpringBootApplication 
@Import({ // @formatter:off 
    JPAConfig.class, 
    ServiceConfig.class, // this contains UserServiceImpl.java class. 
    WebConfig.class, 
    JSFConfig.class, 
}) 
public class SpringbootJpaApplication extends SpringBootServletInitializer{ 

    public static void main(String[] args) { 
     SpringApplication.run(SpringbootJpaApplication.class, args); 
    } 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
      return application.sources(SpringbootJpaApplication.class); 
    } 
} 

托管Bean:

UserBean.java - 托管Bean对JSF

@ManagedBean 
@SessionScoped 
public class UserBean implements Serializable{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private String name; 
    @ManagedProperty(value="#{userServiceImpl}") 
    private UserServiceImpl userServiceImpl; 

    public void addUser(){  
     System.out.println("User Gets added "+this.name);  
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
    public UserServiceImpl getUserServiceImpl() { 
     return userServiceImpl; 
    } 

    public void setUserServiceImpl(UserServiceImpl userServiceImpl) { 
     this.userServiceImpl = userServiceImpl; 
    } 
} 

的Facelets:

home.xhtml - 主页

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:h="http://java.sun.com/jsf/html"> 

    <h:head> 
     <title>JSF 2.0 Hello World</title> 
    </h:head> 
    <h:body> 
     <h2>JSF 2.0 Hello World Example - hello.xhtml</h2> 
     <h:form> 
      <h:inputText value="#{userBean.name}"></h:inputText> 
      <h:commandButton value="Submit" action="#{userBean.addUser}"></h:commandButton> 
     </h:form> 
    </h:body> 
</html> 

faces-config.xml中:

<?xml version="1.0" encoding="UTF-8"?> 
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" 
       version="2.2"> 

    <application> 
     <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> 
    </application> 
    <lifecycle> 
     <phase-listener>org.springframework.web.jsf.DelegatingPhaseListenerMulticaster</phase-listener> 
    </lifecycle> 

</faces-config> 

问题:

1),当我在home.xhtml , userBean.addUser提交表单被调用。 2)userBean.name用用户输入的值设置。 3)但是userServiceImpl是NULL。 4)这是否意味着Spring和JSF没有整合?我也注册SpringBeanFacesELResolver

faces-config.xml 

我也尝试去除UserBean.java所有JSF特定的注释中提到,仅使用过Spring特定的注解像下面 -

@Component 
    @SessionScoped 
    public class UserBean implements Serializable{ 

     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 
     private String name; 
     @Autowired 
     private UserServiceImpl userServiceImpl; 


    } 

但是,当我提交表单,我正在达到目标无法到达#{userBean)的错误。这意味着userBean春季不可发现

5)我在这里丢失了什么? 6)我不使用Spring提供的引导

回答

4

嵌入式的tomcat这是我JSF使用Spring引导工作方式:

1. Servlet的登记

注册JSF servlet和配置它在启动时加载(不需要web.xml)。如果使用JSF 2。2,你最好是用*.xhtml映射,使用小面时至少:

@Bean 
public ServletRegistrationBean servletRegistrationBean() { 
    ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(
      new FacesServlet(), "*.xhtml"); 
    servletRegistrationBean.setLoadOnStartup(1); 
    return servletRegistrationBean; 
} 

让您的配置类实现ServletContextAware,这样你可以设置你的初始化参数。在这里,你必须强制JSF加载配置:

@Override 
public void setServletContext(ServletContext servletContext) { 
    servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", 
      Boolean.TRUE.toString()); 
    servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", "true"); 
    //More parameters... 
} 

2. EL整合

在faces-config.xml中声明EL resolver。这将是您的视图文件和托管bean的属性和方法之间的胶水:

<?xml version="1.0" encoding="UTF-8"?> 
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" 
    version="2.2"> 

    <application> 
     <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver 
     </el-resolver> 
    </application> 

</faces-config> 

3.查看范围

编写自定义春范围模拟JSF的视图范围内(请介意你的bean将由Spring管理,而不是JSF)。它应该有的方式是这样的:

public class ViewScope implements Scope { 

    @Override 
    public Object get(String name, ObjectFactory<?> objectFactory) { 
     Map<String, Object> viewMap = FacesContext.getCurrentInstance() 
      .getViewRoot().getViewMap(); 
     if (viewMap.containsKey(name)) { 
      return viewMap.get(name); 
     } else { 
      Object object = objectFactory.getObject(); 
      viewMap.put(name, object); 
      return object; 
     } 
    } 

    @Override 
    public String getConversationId() { 
     return null; 
    } 

    @Override 
    public void registerDestructionCallback(String name, Runnable callback) { 

    } 

    @Override 
    public Object remove(String name) { 
     return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name); 
    } 

    @Override 
    public Object resolveContextualObject(String arg0) { 
     return null; 
    } 

} 

而且在配置类进行注册:

@Bean 
public static CustomScopeConfigurer viewScope() { 
    CustomScopeConfigurer configurer = new CustomScopeConfigurer(); 
    configurer.setScopes(
      new ImmutableMap.Builder<String, Object>().put("view", new ViewScope()).build()); 
    return configurer; 
} 

4.蓄势待发!

现在您可以按照以下方式声明托管的bean。请记住使用@Autowired(最好在构造函数中)而不是@ManagedProperty,因为你正在处理Spring Beans。

@Component 
@Scope("view") 
public class MyBean { 

    //Ready to go! 

} 

目前仍在等待实现

我不能让JSF特定注释在Spring上下文引导工作。所以@FacesValidator,@FacesConverter,@FacesComponent等都不能使用。尽管如此,仍然有机会在faces-config.xml中声明它们(请参阅xsd),这是一种老式的方式。


参见:

+0

的Xtreme骑自行车的人,你找到一个办法让JSF注释工作?也许与春季启动2.0? –

+0

不,但自从我写这个答案以来,我没有太多挖掘。因为Spring在这里管理你的bean,所以你可以尝试一些生成单例的注释,就像@Component一样。 –