Spring Boot JSF Integration
环境 :
雄猫8
春季靴1.5
JSF 2.2
阿帕奇MyFaces
春季MVC
代码:
我正在Servlet 3.0环境中集成Spring Boot和JSF 2.2。
配置类:
JSFConfig.java-JSF的配置。
1 2 3 4 5 6 7 8 9 10 11 | @Configuration @ComponentScan({"com.atul.jsf"}) public class JSFConfig { @Bean public ServletRegistrationBean servletRegistrationBean() { FacesServlet servlet = new FacesServlet(); return new ServletRegistrationBean(servlet,"*.jsf"); } } |
Spring Boot主类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @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); } } |
托管豆:
UserBean.java-JSF的托管Bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | @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-主页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?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> JSF 2.0 Hello World </h:head> <h:body> JSF 2.0 Hello World Example - hello.xhtml <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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?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"> <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)当我在
2)
3)但是
4)这是否意味着Spring和JSF没有集成?我还注册了
1 | faces-config.xml |
我还尝试了从UserBean.java中删除所有JSF特定注释,仅使用了Spring特定注释,如下所示-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Component @SessionScoped public class UserBean implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String name; @Autowired private UserServiceImpl userServiceImpl; } |
但是,当我提交表单时,出现了
5)我在这里想念什么吗?
6)我没有使用Spring Boot提供的嵌入式tomcat
这是我让JSF与Spring Boot一起工作的方式(Github上的完整示例项目,已由JSF 2.3和Spring Boot 2更新):
1.依存关系
除了标准的Web Starter依赖项之外,您还需要包括标记为提供的tomcat嵌入式jasper(感谢@Fencer在此处发表评论)。否则,由于JSF取决于JSP处理器,您将在应用程序启动时遇到异常(另请参见答案末尾的第一个链接)。
1 2 3 4 5 6 7 8 9 10 | <dependency> <groupId>org.apache.tomcat.embed</groupId> tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> spring-boot-starter-web</artifactId> </dependency> |
2. Servlet注册
注册JSF Servlet并将其配置为在启动时加载(不需要web.xml)。如果使用JSF 2.2,则最好是至少在使用facelet时使用
1 2 3 4 5 6 7 | @Bean public ServletRegistrationBean servletRegistrationBean() { ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean( new FacesServlet(),"*.xhtml"); servletRegistrationBean.setLoadOnStartup(1); return servletRegistrationBean; } |
使您的配置类实现
1 2 3 4 5 6 7 | @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属性和方法之间的粘合剂:
1 2 3 4 5 6 7 8 9 10 11 12 | <?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"> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver </el-resolver> </application> </faces-config> |
4.视图范围
编写一个自定义的Spring范围来模拟JSF视图范围(请注意,您的bean将由Spring而不是JSF管理)。它看起来应该像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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; } } |
并将其注册到您的配置类中:
1 2 3 4 5 6 7 | @Bean public static CustomScopeConfigurer viewScope() { CustomScopeConfigurer configurer = new CustomScopeConfigurer(); configurer.setScopes( new ImmutableMap.Builder<String, Object>().put("view", new ViewScope()).build()); return configurer; } |
5.准备出发!
现在,您可以按照以下方式声明托管bean。记住要使用
1 2 3 4 5 6 7 | @Component @Scope("view") public class MyBean { //Ready to go! } |
仍有待实现
我无法在Spring Boot上下文中使用JSF特定的注释。因此,不能使用
也可以看看:
- 使用JSF的Spring Boot;找不到工厂javax.faces.context.FacesContextFactory的备份
- 将JSF 2.0的ViewScope移植到Spring 3.0
- Spring Boot Web应用程序中未呈现JSP文件