簡體   English   中英

Spring Boot JSF集成

[英]Spring Boot JSF Integration

環境 :

雄貓8

Spring Boot 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");
        }

}

Spring Boot主類:

@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 - JSF的托管Bean

@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;
    }
}

小面孔:

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提交表單時home.xhtml , userBean.addUser會調用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)目標無法訪問錯誤。 這意味着Spring不能發現userBean

我在這里錯過了什么嗎? 6)我沒有使用Spring Boot提供的嵌入式tomcat

這是我讓JSF使用Spring Boot的方式( Github上的完整示例項目,使用JSF 2.3和Spring Boot 2更新 ):

1.依賴性

除了標准的Web啟動程序依賴項之外,您還需要包含標記為提供的tomcat嵌入式jasper(感謝@Fencer在此處進行注釋)。 否則你會在應用程序啟動時遇到異常,因為JSF依賴於JSP處理器(另請參閱我的答案末尾的第一個鏈接)。

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. Servlet注冊

注冊JSF servlet並將其配置為在啟動時加載(不需要web.xml)。 如果使用JSF 2.2,最好使用*.xhtml映射,至少在使用facelets時:

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

使您的配置類實現ServletContextAware以便您可以設置init參數。 在這里你必須強制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...
}

3. EL集成

在faces-config.xml中聲明EL解析器 這將成為視圖文件與托管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>

4.視圖范圍

編寫一個自定義的Spring作用域來模擬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;
}

准備好了!

現在,您可以按照以下方式聲明托管bean。 記得使用@Autowired (最好是在構造函數中)而不是@ManagedProperty ,因為你正在處理Spring Beans。

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

    //Ready to go!

}

仍有待實現

我無法在Spring Boot上下文中獲得JSF特定的注釋。 所以@FacesValidator@FacesConverter@FacesComponent等。 仍然有機會在faces-config.xml中聲明它們(參見xsd ),這是一種老式的方式。


也可以看看:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM