我所拥有的是一个简单的helloworld应用程序,它利用JSF和带有Maven的Spring。每当我从ManagedBean中调用BO(业务对象)时,BO总是为空。我不确定我遗漏了什么或不理解什么。
HelloWorldMB.java
package com.project.web;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import tech.calvanodesign.business.HelloWorldBo;
import java.io.Serializable;
@ManagedBean
@SessionScoped
public class HelloWorldMB implements Serializable {
public HelloWorldBo helloWorldBo;
private static final long serialVersionUID = 1L;
private String name;
public void init () {
System.out.println("HelloWorldMB.init()");
if (helloWorldBo != null)
return;
System.out.println("helloWorldBo is null");
}
public String springTest() {
// Call the business object to register the user
helloWorldBo.springTest(name);
return "";
}
// Set the registrationBo attribute used by Spring
public void setHelloWorldBo(HelloWorldBo helloWorldBo) {
this.helloWorldBo = helloWorldBo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
欢迎.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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>JSF 2.0 Hello World</title>
<h:outputStylesheet library="css" name="style.css" />
</h:head>
<h:body>
<h:form>
<p:growl id="growl" showDetail="true" sticky="true" />
<p:inputText id="intxtSpringTest" value="#{helloWorldMB.name}"/>
<p:commandButton id="cmdbtnSpringTest" value="Test Spring 3 with JSF" action="#{helloWorldMB.springTest}" ajax="false"/>
</p:panel>
</h:form>
</h:body>
HelloWorldBo.java
package com.project.business;
public interface HelloWorldBo {
/**
* springTest method
* @param name
*/
public void springTest(String name);
}
HelloWorldBoImpl
package com.project.business;
public class HelloWorldBoImpl implements HelloWorldBo {
/**
* Tests the spring and jsf implementation
*/
@Override
public void springTest(String name) {
System.out.println("HelloWorldBoImpl:: springTest : " + name);
}
}
面向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
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>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tech.calvanodesign</groupId>
<artifactId>calvanodesignsource</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>calvanodesignsource Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.0</version>
</dependency>
<!-- spring-context which provides core functionality -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>calvanodesignsource</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
https://github.com/Epooch/CalvanoDesignSource
那些希望看到整个应用程序在我的机器上的来源。
对于那些遇到问题的人来说,代码块将保持原样。我将在下面发布我为使其发挥作用所做的更改。
工作解决方案
HelloWorldMB
package com.project.web;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import com.project.business.HelloWorldBo;
import java.io.Serializable;
@ManagedBean
@SessionScoped
public class HelloWorldMB implements Serializable {
@ManagedProperty(value = "#{helloWorldBo}")
private HelloWorldBo helloWorldBo;
private static final long serialVersionUID = 1L;
private String name;
public void init () {
System.out.println("HelloWorldMB.init()");
if (helloWorldBo != null)
return;
System.out.println("helloWorldBo is null");
}
public void springTest(ActionEvent e) {
// Call the business object to register the user
helloWorldBo.springTest(name);
}
// Set the registrationBo attribute used by Spring
public void setHelloWorldBo(HelloWorldBo helloWorldBo) {
this.helloWorldBo = helloWorldBo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
HelloWorldBo
package com.project.business;
public interface HelloWorldBo {
/**
* springTest method
* @param name
*/
public void springTest(String name);
}
HelloWorldBoImpl
package com.project.business;
import javax.inject.Named;
@Named("helloWorldBo")
public class HelloWorldBoImpl implements HelloWorldBo {
/**
* Tests the spring and jsf implementation
*/
@Override
public void springTest(String name) {
System.out.println("HelloWorldBoImpl:: springTest : " + name);
}
}
向pom.xml添加了以下依赖项
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
如果希望Spring注入业务对象,则必须为JSF提供一些解析bean引用的方法。托管bean必须在JSF生命周期中调用的方法中的某个位置初始化业务对象。
例如,以下是一个简单示例中的相关部分。
首先,您需要web应用程序描述符中的Spring设置:
/WEB-INF/WEB.xml
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/app-service-config.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
/WEB-INF/app服务配置.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Spring 3.1 annotation support -->
<context:component-scan base-package="com.rtt.simple.service" />
然后,您需要用一个解析器来设置JSF,让它在其托管bean中注入Springbean。
面向config.xml
<application>
<!-- Spring Framework support -->
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
然后,您可以在托管bean中注入一个Spring bean:
DummyBackingBean.java
@ManagedBean
@ViewScoped
public class DummyBackingBean implements Serializable {
@ManagedProperty(value = "#{dummyService}")
private DummyService dummyService;
private List<DummyDataItem> dataItems;
@PostConstruct
public void postConstruct() {
LOG.trace("postConstruct()");
dataItems = dummyService.listAll();
}
public DummyService getDummyService() {
return dummyService;
}
public void setDummyService(DummyService dummyService) {
this.dummyService = dummyService;
}
DummyService.java
package com.rtt.simple.service;
import javax.inject.Named;
import com.rtt.simple.domain.DummyDataItem;
@Named("dummyService")
public class DummyService {
private static List<DummyDataItem> dataItems;
public List<DummyDataItem> listAll() {
return dataItems;
}
static {
dataItems = new ArrayList<DummyDataItem>();
// Initialize the dataItems list with static data
请注意,我使用了javax.inject中的@Named注释来声明Spring配置中的bean,但这种技术将适用于任何Spring注入注释。