環境:
Tomcat 8
スプリングブーツ1.5
JSF 2.2
Apache MyFaces
春MVC
コード:
Spring BootとJSF 2.2をServlet 3.0環境に統合しています。
構成クラス:
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-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;
}
}
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
はSpringで検出できません
5)ここで何か不足していますか? 6)Spring Bootに付属の組み込みTomcatを使用していません
これは、JSFがSpring Bootで動作する方法です(完全 Githubのサンプルプロジェクト、JSF 2.3およびSpring Boot 2で更新 ):
1。依存関係
標準のWebスターター依存関係に加えて、提供済みとしてマークされたTomcat埋め込みジャスパーを含める必要があります(@ ここ でコメントしてくれた@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。サーブレット登録
JSFサーブレットを登録し、起動時にロードするように構成します(web.xmlは不要)。 JSF 2.2を使用している場合、少なくともfaceletsを使用する場合は、*.xhtml
マッピングを使用することをお勧めします。
@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 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>
4。ビューのスコープ
JSFビュースコープをエミュレートするカスタムSpringスコープを記述します(BeanはJSFではなくSpringによって管理されることに注意してください)。次のようになります。
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;
}
5。準備完了!
これで、マネージドBeanを以下の方法で宣言できます。 Spring Beanを扱っているため、@Autowired
の代わりに@ManagedProperty
(できればコンストラクタ内)を使用することを忘れないでください。
@Component
@Scope("view")
public class MyBean {
//Ready to go!
}
達成するためにまだ保留中
Spring BootコンテキストでJSF固有のアノテーションを機能させることができませんでした。したがって、@FacesValidator
、@FacesConverter
、@FacesComponent
などは使用できません。それでも、faces-config.xmlでそれらを宣言する機会があります( xsd を参照)、昔ながらの方法です。
以下も参照してください: