本教程是第1部分的继续。
让我们创建一个新的Dynamic Web Project 。 如下图所示创建它:
注意:在某些时候,Eclipse会询问您是否要添加JSF功能(自动完成),然后启用它。 就像下面的屏幕一样:
创建项目后,让我们编辑“ web.xml”文件; 它应该具有与以下相同的代码:
<?xml version='1.0' encoding='UTF-8'?>
<web-app xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://java.sun.com/xml/ns/javaee' xmlns:web='http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd'
xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd'
id='WebApp_ID' version='3.0'>
<display-name>CrudJSF</display-name>
<welcome-file-list>
<welcome-file>pages/protected/user/listAllDogs.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.jsf</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- Protected area definition -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted Area - ADMIN Only</web-resource-name>
<url-pattern>/pages/protected/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted Area - USER and ADMIN</web-resource-name>
<url-pattern>/pages/protected/user/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>USER</role-name>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<!-- Login page -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/pages/public/login.xhtml</form-login-page>
<form-error-page>/pages/public/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>
<!-- System roles -->
<security-role>
<role-name>ADMIN</role-name>
</security-role>
<security-role>
<role-name>USER</role-name>
</security-role>
</web-app>
您不必担心是否会出现一些警告/错误。 我们稍后会解决。 请注意,我已经添加了我们需要的所有JAAS代码(如果您想获得有关这些JAAS配置的详细信息,可以在此处进行检查: 使用JAAS和JSF的用户登录验证 )。
根据JAAS的配置,普通用户(USER角色)将只看到用户文件夹中的文件,而这些文件仅仅是我们数据库中记录的狗的列表; ADMIN将能够执行所有CRUD操作,因为所有页面都位于admins文件夹内。
我们的“ faces-config.xml”应具有以下代码:
<?xml version='1.0' encoding='UTF-8'?>
<faces-config
xmlns='http://java.sun.com/xml/ns/javaee'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd'
version='2.0'>
<navigation-rule>
<navigation-case>
<from-outcome>logout</from-outcome>
<to-view-id>/pages/protected/user/listAllDogs.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<navigation-rule>
<navigation-case>
<from-outcome>listAllDogs</from-outcome>
<to-view-id>/pages/protected/user/listAllDogs.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<navigation-case>
<from-outcome>createDog</from-outcome>
<to-view-id>/pages/protected/admin/createDog.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<navigation-rule>
<navigation-case>
<from-outcome>updateDog</from-outcome>
<to-view-id>/pages/protected/admin/updateDog.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<navigation-case>
<from-outcome>deleteDog</from-outcome>
<to-view-id>/pages/protected/admin/deleteDog.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<application>
<resource-bundle>
<base-name>messages</base-name>
<var>msgs</var>
</resource-bundle>
</application>
</faces-config>
注意,对于某些操作,我使用了重定向操作。 通过此操作,我们将更新浏览器URL栏中的请求链接,URL更新后,JAAS将拒绝对非法用户的访问。
我们还有一个文件,其中包含我们系统的所有消息。 您会注意到,页面中显示的所有文本都在此文件中(在src文件夹中创建一个名为“ messages.properties”的文件):
#Dog
dog=Dog
dogName=Name
dogWeight=Weight
#Dog messages
dogCreateHeader=Create a new Dog
dogUpdateHeader=Update the Dog
dogDeleteHeader=Delete this Dog
dogNameRequired=The dog needs a name.
dogWeightRequired=The dog needs a weight.
#Actions
update=Update
create=Create
delete=Delete
cancel=Cancel
#Login
loginHello=Hello
loginErrorMessage=Could not login. Check you UserName/Password
loginUserName=Username
loginPassword=Password
logout=Log Out
视图–创建和JSF设置
现在让我们创建ManagedBeans。
首先,我们需要将EJB添加到Web项目中。 用鼠标右键单击JSF项目>属性:
Java构建路径>项目>添加>检查CrudEJB>确定
首先,让我们创建DogMB:
package com.mb;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import com.facade.DogFacade;
import com.model.Dog;
@ManagedBean
@RequestScoped
public class DogMB {
@EJB
private DogFacade dogFacade;
private static final String CREATE_DOG = 'createDog';
private static final String DELETE_DOG = 'deleteDog';
private static final String UPDATE_DOG = 'updateDog';
private static final String LIST_ALL_DOGS = 'listAllDogs';
private static final String STAY_IN_THE_SAME_PAGE = null;
private Dog dog;
public Dog getDog() {
if(dog == null){
dog = new Dog();
}
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public List<Dog> getAllDogs() {
return dogFacade.findAll();
}
public String updateDogStart(){
return UPDATE_DOG;
}
public String updateDogEnd(){
try {
dogFacade.update(dog);
} catch (EJBException e) {
sendErrorMessageToUser('Error. Check if the weight is above 0 or call the adm');
return STAY_IN_THE_SAME_PAGE;
}
sendInfoMessageToUser('Operation Complete: Update');
return LIST_ALL_DOGS;
}
public String deleteDogStart(){
return DELETE_DOG;
}
public String deleteDogEnd(){
try {
dogFacade.delete(dog);
} catch (EJBException e) {
sendErrorMessageToUser('Error. Call the ADM');
return STAY_IN_THE_SAME_PAGE;
}
sendInfoMessageToUser('Operation Complete: Delete');
return LIST_ALL_DOGS;
}
public String createDogStart(){
return CREATE_DOG;
}
public String createDogEnd(){
try {
dogFacade.save(dog);
} catch (EJBException e) {
sendErrorMessageToUser('Error. Check if the weight is above 0 or call the adm');
return STAY_IN_THE_SAME_PAGE;
}
sendInfoMessageToUser('Operation Complete: Create');
return LIST_ALL_DOGS;
}
public String listAllDogs(){
return LIST_ALL_DOGS;
}
private void sendInfoMessageToUser(String message){
FacesContext context = getContext();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
}
private void sendErrorMessageToUser(String message){
FacesContext context = getContext();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message));
}
private FacesContext getContext() {
FacesContext context = FacesContext.getCurrentInstance();
return context;
}
}
关于上面的代码:
- 您将在faces-config.xml中找到所有导航。 您应该在页面导航中使用常量或资源包; 与仅在方法中保留字符串相比,这种方法是一种更好的方法。
- 注意,我们仅使用@EJB将EJB注入MB内。 发生这种情况是因为我们正在使用同一个EAR中的所有东西。 JBoss 7使这种本地化变得容易。
- 如果注入不适用于JBoss 6(或者在EAR之外使用EJB jar),则可以使用如下注入:@EJB(mappedName =“ DogFacadeImp / local”)。
- 注意,将向我们的系统用户显示一条消息。 我们会对在Façade中执行的每个动作进行尝试/捕获,如果发生某些错误,我们将向用户发送错误消息。
- 正确的操作是验证ManagedBean和Façade中的数据。 这些验证的CPU成本较低。
- 如果您正在使用JBoss 4.2,则需要像下面的代码那样进行JNDI查找(就像本文前面所说的那样,使用LocalBinding批注)。 像这样注释您的班级:
@Stateless @LocalBinding(jndiBinding='MyBean') public class MyBeanImp implements MyBean{ @Override public String hello() { return 'Value From EJB'; } } // In your Servlet class you would lookup like the code bellow: public class Inject extends HttpServlet { private MyBean local; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { InitialContext iniCtx = new InitialContext(); local = (MyBean) iniCtx.lookup('MyBean'); } catch (NamingException e) { e.printStackTrace(); } System.out.println(local.hello()); request.getRequestDispatcher('/finish.jsp').forward(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
现在,让我们看看UserMB:
package com.mb;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import com.facade.UserFacade;
import com.model.User;
@SessionScoped
@ManagedBean
public class UserMB {
private User user;
@EJB
private UserFacade userFacade;
public User getUser(){
if(user == null){
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
String userEmail = context.getUserPrincipal().getName();
user = userFacade.findUserByEmail(userEmail);
}
return user;
}
public boolean isUserAdmin(){
return getRequest().isUserInRole('ADMIN');
}
public String logOut(){
getRequest().getSession().invalidate();
return 'logout';
}
private HttpServletRequest getRequest() {
return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
}
}
关于上面的代码:
- 该MB仅用于存储我们应用程序的会话用户。 您将使用此MB显示用户名或有关应用程序用户的任何其他操作。
- 注意,这是一个会话MB; 我们只检查一次用户是否为null,如果返回true,我们将转到数据库。 在这种情况下,我们将只获得一次数据库保存性能。
- 如果@EJB注入引发异常,请检查上面DogMB中给出的技巧。
查看–页面
下面是页面,css及其各自的路径:
不要介意上面图片中显示的询问图标或任何其他图标类型。 这些是指向我的代码的版本控制图标。 始终保存您的代码。
我在ManagedBean中使用RequestScope,这就是为什么您会在所有页面中看到h:inputHidden的原因。 我认为用RequestScope MB重复此字段是一种更好的方法,因为您将拥有更多的可用内存,而不是使用SessionScope MB。
/WebContent/resources/css/main.css
.table {
border-collapse: collapse;
}
.tableColumnsHeader {
text-align: center;
background: none repeat scroll 0 0 #E5E5E5;
border-bottom: 1px solid #BBBBBB;
padding: 16px;
}
.tableFirstLine {
text-align: center;
background: none repeat scroll 0 0 #F9F9F9;
border-top: 1px solid #BBBBBB;
}
.tableNextLine {
text-align: center;
background: none repeat scroll 0 0 #FFFFFFF;
border-top: 1px solid #BBBBBB;
}
.panelGrid {
border: 1px solid;
}
.panelFirstLine {
text-align: center;
border-top: 1px solid #BBBBBB;
}
.panelNextLine {
text-align: center;
border-top: 1px solid #BBBBBB;
}
/WebContent/pages/public/login.xhtml
<!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'
xmlns:ui='http://java.sun.com/jsf/facelets'>
<h:head>
<h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
<p>Login to access secure pages:</p>
<form method='post' action='j_security_check'>
<h:messages layout='table' errorStyle='background: #AFEEEE;'
infoStyle='background: #AFEEEE;' globalOnly='true' />
<h:panelGrid columns='2'>
<h:outputLabel value='Username: ' />
<input type='text' id='j_username' name='j_username' />
<h:outputLabel value='Password: ' />
<input type='password' id='j_password' name='j_password' />
<h:outputText value='' />
<h:panelGrid columns='1'>
<input type='submit' name='submit' value='Login' />
</h:panelGrid>
</h:panelGrid>
<br />
</form>
</h:body>
</html>
注意我们如何像导入库一样导入css。 您在form标签中看到的动作指向我们一个未知的动作,但是JAAS负责管理该动作。
/WebContent/pages/public/loginError.xhtml
<!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'
xmlns:ui='http://java.sun.com/jsf/facelets'>
<h:head>
<h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
#{msgs.loginErrorMessage}
</h:body>
</html>
/WebContent/pages/protected/user/listAllDogs.xhtml
<!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'
xmlns:ui='http://java.sun.com/jsf/facelets'>
<h:head>
<h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
<h:form>
<h3>#{msgs.loginHello}: #{userMB.user.name} || <h:commandLink action='#{userMB.logOut()}' value='#{msgs.logout}' /> </h3>
<h:messages />
<h:dataTable value='#{dogMB.allDogs}' var='dog' styleClass='table' headerClass='tableColumnsHeader' rowClasses='tableFirstLine,tableNextLine' >
<h:column>
<f:facet name='header'>
#{msgs.dogName}
</f:facet>
#{dog.name}
</h:column>
<h:column>
<f:facet name='header'>
#{msgs.dogWeight}
</f:facet>
#{dog.weight}
</h:column>
<h:column>
<h:panelGrid columns='2'>
<!-- Always save the id as hidden when you use a request scope MB -->
<h:inputHidden value='#{dog.id}' />
<h:commandButton action='#{dogMB.updateDogStart()}' value='#{msgs.update}' rendered='#{userMB.userAdmin}' >
<f:setPropertyActionListener target='#{dogMB.dog}' value='#{dog}' />
</h:commandButton>
<h:commandButton action='#{dogMB.deleteDogStart()}' value='#{msgs.delete}' rendered='#{userMB.userAdmin}' >
<f:setPropertyActionListener target='#{dogMB.dog}' value='#{dog}' />
</h:commandButton>
</h:panelGrid>
</h:column>
</h:dataTable>
<!-- This button is displayed to the user, just to you see the error msg -->
<h:commandButton action='createDog' value='#{msgs.create} #{msgs.dog}' />
</h:form>
</h:body>
</html>
关于上面的代码:
- 永远记得用h:form标记包装代码。 如果没有h:form,h:head和h:body,有些框架(例如Primefaces)将无法工作。
- 我们使用UserMB来显示用户名并注销我们的用户。
- <h:messages />标记将显示DogMB发送的消息。
- 请注意,第33行的ID被隐藏。 如果您使用RequestScope而不是SessionScope,则这是一个必需的值。 我宁愿使用RequestScope也不使用SessionScope,因为服务器内存中的数据更少。
- 请注意,按钮的呈现方式为=“#{userMB.userAdmin}”,以指示仅ADMIN角色有权访问删除/更新。
- 我通过标签“ f:setPropertyActionListener ”将选定的狗传递给我的MB。
- “创建”按钮没有渲染选项。 如果普通用户尝试访问页面,它只是向您显示。
/WebContent/pages/protected/admin/createDog.xhtml
<!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'
xmlns:ui='http://java.sun.com/jsf/facelets'>
<h:head>
<h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
<h:form>
<h:messages/>
<h3>${msgs.dogCreateHeader}</h3>
<h:panelGrid columns='2' styleClass='panelGrid' rowClasses='panelFirstLine,panelNextLine' >
<h:outputLabel for='dogName' value='#{msgs.dogName}' />
<h:inputText id='dogName' value='#{dogMB.dog.name}' required='true' requiredMessage='#{msgs.dogNameRequired}' />
<h:outputLabel for='dogWeight' value='#{msgs.dogWeight}' />
<h:inputText id='dogWeight' value='#{dogMB.dog.weight}' required='true' requiredMessage='#{msgs.dogWeightRequired}' >
<f:convertNumber />
</h:inputText>
</h:panelGrid>
<h:panelGrid columns='2'>
<h:commandButton action='#{dogMB.createDogEnd()}' value='#{msgs.create}' />
<h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' />
</h:panelGrid>
<br/>
</h:form>
</h:body>
</html>
关于上面的代码:
- 字段名称和权重是必填字段,如果将其保留为空,则会显示一条错误消息。
- 取消按钮需要选项Instant =“ true”; 使用此选项,JSF将不会验证任何字段。
/WebContent/pages/protected/admin/deleteDog.xhtml
<!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'
xmlns:ui='http://java.sun.com/jsf/facelets'>
<h:head>
<h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
<h:form>
<h:messages/>
<h3>#{msgs.dogDeleteHeader}: #{dogMB.dog.name}?</h3>
<h:inputHidden value='#{dogMB.dog.id}' />
<h:panelGrid columns='2'>
<h:commandButton action='#{dogMB.deleteDogEnd()}' value='#{msgs.delete}' />
<h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' />
</h:panelGrid>
<br/>
</h:form>
</h:body>
</html>
请注意,在第15行中,该ID是隐藏的。 如果您使用RequestScope而不是SessionScope,则这是一个必需的值。 我宁愿使用RequestScope也不使用SessionScope,因为服务器内存中的数据更少。
/WebContent/pages/protected/admin/updateDog.xhtm l
<!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'
xmlns:ui='http://java.sun.com/jsf/facelets'>
<h:head>
<h:outputStylesheet library='css' name='main.css' />
</h:head>
<h:body>
<h:form>
<h:messages/>
<h3>#{msgs.dogUpdateHeader}: #{dogMB.dog.name}</h3>
<h:inputHidden value='#{dogMB.dog.id}' />
<h:panelGrid columns='2' styleClass='panelGrid' rowClasses='panelFirstLine,panelNextLine' >
<h:outputLabel for='dogName' value='#{msgs.dogName}' />
<h:inputText id='dogName' value='#{dogMB.dog.name}' required='true' requiredMessage='#{msgs.dogNameRequired}' />
<h:outputLabel for='dogWeight' value='#{msgs.dogWeight}' />
<h:inputText id='dogWeight' value='#{dogMB.dog.weight}' required='true' requiredMessage='#{msgs.dogWeightRequired}' >
<f:convertNumber />
</h:inputText>
</h:panelGrid>
<h:panelGrid columns='2'>
<h:commandButton action='#{dogMB.updateDogEnd()}' value='#{msgs.update}' />
<h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' />
</h:panelGrid>
<br/>
</h:form>
</h:body>
</html>
关于上面的代码:
- 请注意,在第15行中,该ID是隐藏的。 如果您使用RequestScope而不是SessionScope,则这是一个必需的值。 我宁愿使用RequestScope也不使用SessionScope,因为服务器内存中的数据更少。
- 字段名称和权重是必填字段,如果将其保留为空,则会显示一条错误消息。
- 取消按钮需要选项Instant =“ true”; 使用此选项,JSF将不会验证任何字段。
查看– JBoss 7 JAAS配置
现在,我们只需要完成一些步骤即可完成我们的软件(最后!)。
我们需要编辑JBoss配置并添加我们的JAAS配置。
再次打开文件“ YOUR_JBOSS / standalone / configuration / standalone.xml ”,然后搜索密钥:“ <security-domains>”。 添加下面的代码(在这篇文章中,我演示如何为JBoss 6 – 使用JAAS和JSF进行用户登录验证 )进行设置:
<subsystem xmlns='urn:jboss:domain:security:1.0'>
<security-domains>
<!-- add me: begin -->
<security-domain name='CrudJSFRealm' cache-type='default'>
<authentication>
<login-module code='org.jboss.security.auth.spi.DatabaseServerLoginModule' flag='required'>
<module-option name='dsJndiName' value='CrudDS'/>
<module-option name='principalsQuery' value='select password from users where email=?' />
<module-option name='rolesQuery' value='select role, 'Roles' from users u where u.email=?' />
</login-module>
</authentication>
</security-domain>
<!-- add me: end -->
<!-- Other data... -->
</security-domains>
</subsystem>
运行我们的应用程序
让我们创建一个EAR来统一我们的项目。
文件>新建>其他> EnterpriseApplication项目
我们只需要在我们的JBoss中添加EAR。
让我们运行我们的应用程序。 启动JBoss并通过以下URL访问我们的应用程序: http:// localhost:8080 / CrudJSF / 。
我使用简单CSS编写了页面,以使理解更加容易。
以USER身份登录,您将不会看到更新/删除按钮; 您只会看到我们留在此处的“创建”按钮,只是为了查看非法访问的例外情况。
看一下我们的页面:
记录为ADMIN:
以USER身份登录:
今天就这些
要下载此帖子的源代码, 请单击此处 。
希望这篇文章对您有所帮助。
如果您有任何疑问或评论,请在下面将其发布。
再见。 \ o_
对我有帮助的链接:
http://7thursdays.wordpress.com/2008/03/18/dependency-injection-in-jboss-42-hold-your-excitement/
http://jan.zawodny.pl/blog/2011/07/jboss-7-postgresql-9
http://blog.xebia.com/2011/07/19/developing-a-jpa-application-on-jboss-as-7/
http://community.jboss.org/wiki/DataSourceConfigurationInAS7
http://www.mkyong.com/jsf2/jsf-2-datatable-example/
参考: uaiHebert博客上来自我们的JCG合作伙伴 Hebert Coelho的完整WebApplication JSF EJB JPA JAAS 。
翻译自: https://www.javacodegeeks.com/2012/06/full-webapplication-jsf-ejb-jpa-jaas_19.html