2017-09-13 170 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一樣。 –