javascript
完整的WebApplication JSF EJB JPA JAAS –第1部分
在本文的結(jié)尾,您將找到要下載的源代碼。 您可以根據(jù)需要使用它。 只需轉(zhuǎn)到最后一頁并進(jìn)行下載。 \ o /
如果您下載了代碼但不了解某些內(nèi)容,則在本文中,我將解釋代碼中找到的每個(gè)詳細(xì)信息。 只需閱讀此帖子中想要的主題即可。
我將在下面列出我將在本文中使用的技術(shù):
- JSF 2.0 Mojarra –使用ManagedBeans作為RequestScope和SessionScope。
- 消息國(guó)際化–包含我們系統(tǒng)所有消息的文件; 輕松翻譯您的頁面。
- 將作為庫導(dǎo)入的默認(rèn)CSS文件。
- EJB 3 –我們的DAO和Fa?ades將是@Stateless。
- 通用DAO –通用DAO,它將執(zhí)行CRUD動(dòng)作以使我們的生活更輕松。
- JPA 2 –在數(shù)據(jù)庫中映射我們的類
- JAAS –控制登錄和用戶對(duì)頁面的訪問。
- MVC –我將使用此模式進(jìn)行少量修改。
- Postgres作為數(shù)據(jù)庫,但我還將展示如何將您的應(yīng)用設(shè)置為MySQL。
我不會(huì)使用TDD – JUnit測(cè)試我們的View / Model / Classes,但是在下面的鏈接中,您可以看到一種使用JUnit測(cè)試您的ManagedBeans的技術(shù): 具有HSQLDB,JPA和Hibernate的JUnit 。
我們將使用的工具:
- Eclipse Indigo – http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/indigor
- 我將使用JBoss 7(此博客的某些讀者問我了)– http://download.jboss.org/jbossas/7.0/jboss-as-7.0.2.Final/jboss-as-7.0.2.Final。 .zip的版本是: JBoss 7 Everything(未通過Java EE6認(rèn)證) 。
- Indigo JBoss工具(里程碑版本)– https://www.jboss.org/tools/download/dev.html如果您不知道如何在本文中安裝JBoss工具,我將展示如何( 使用JAAS進(jìn)行用戶登錄驗(yàn)證和JSF )。 請(qǐng)注意,在這篇文章中,我將展示如何安裝到另一個(gè)eclipse版本,但是區(qū)別在于URL。 使用此URL代替上面鏈接中使用的URL: http : //download.jboss.org/jbosstools/updates/development/indigo/
- 我將使用Postgres數(shù)據(jù)庫,但您可以使用所需的任何數(shù)據(jù)庫。 您只需要下載數(shù)據(jù)庫和JDBC驅(qū)動(dòng)程序。 在這里,您可以下載最新的Postgres JDBC: http : //jdbc.postgresql.org/download.html ; 到目前為止,最新版本是4: http : //jdbc.postgresql.org/download/postgresql-9.1-901.jdbc4.jar 。
這篇文章將有幾頁; 這第一頁只是顯示今天帖子的技術(shù)細(xì)節(jié)。
我不會(huì)編寫代碼來連接模型/ DAO,只是為了節(jié)省空間。 請(qǐng)記住,您應(yīng)該始終對(duì)接口進(jìn)行編碼( 設(shè)計(jì)模式-策略 ) 。
在繼續(xù)之前,請(qǐng)確保以正確的順序安裝了JBoss工具和JBoss 7。
商業(yè)模式
讓我們創(chuàng)建將容納我們的系統(tǒng)業(yè)務(wù)的EJB項(xiàng)目。
點(diǎn)擊“ 完成 ”按鈕。
讓我們創(chuàng)建將在“ com”包中的User和Dog類。 它將具有以下代碼:
package com.model;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQuery; import javax.persistence.Table;@Entity @Table(name = 'USERS') @NamedQuery(name='User.findUserByEmail', query='select u from User u where u.email = :email') public class User {public static final String FIND_BY_EMAIL = 'User.findUserByEmail';@Id@GeneratedValue(strategy=GenerationType.AUTO)private int id;@Column(unique = true)private String email;private String password;private String name;private String role;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getRole() {return role;}public void setRole(String role) {this.role = role;}@Overridepublic int hashCode() {return getId();}@Overridepublic boolean equals(Object obj) {if(obj instanceof User){User user = (User) obj;return user.getEmail().equals(getEmail());}return false;} }package com.model;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;@Entity @Table(name = 'DOGS') public class Dog {@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id;private String name;private double weight;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}@Overridepublic int hashCode() {return getId();}@Overridepublic boolean equals(Object obj) {if(obj instanceof Dog){Dog dog = (Dog) obj;return dog.getId() == getId();}return false;} }關(guān)于上面的代碼:
- User類具有一個(gè)名為“ role”的字段,該字段將存儲(chǔ)用戶的角色級(jí)別。 我將其創(chuàng)建為一個(gè)字段,并將所有數(shù)據(jù)保留在同一表中,以便于理解。 如果您想要有關(guān)JAAS的更多詳細(xì)信息,可以在這篇文章中: 使用JAAS和JSF進(jìn)行用戶登錄驗(yàn)證 。
- 我將讓JPA處理表ID代。 如果要更改ID的創(chuàng)建方式,可以查看以下文章以了解如何執(zhí)行: JPA SequenceGenerator , JPA TableGenerator –簡(jiǎn)單Primay密鑰 。
- 該電子郵件將是唯一的; 這將是登錄標(biāo)識(shí)符。
- 注意,要聲明為Entity的類,只需要以下注釋:“ @Entity”和“ @Id”。 該類不需要實(shí)現(xiàn)Serializable接口。
商業(yè)– DAO
我將使用通用DAO進(jìn)行基本的CRUD操作,而其他兩個(gè)DAO:一個(gè)用于User,另一個(gè)用于Dog。 理解它的用法將非常容易:
package com.dao;import java.util.List; import java.util.Map; import java.util.Map.Entry;import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.criteria.CriteriaQuery;public abstract class GenericDAO<T> {private final static String UNIT_NAME = 'CrudPU';@PersistenceContext(unitName = UNIT_NAME)private EntityManager em;private Class<T> entityClass;public GenericDAO(Class<T> entityClass) {this.entityClass = entityClass;}public void save(T entity) {em.persist(entity);}public void delete(T entity) {T entityToBeRemoved = em.merge(entity);em.remove(entityToBeRemoved);}public T update(T entity) {return em.merge(entity);}public T find(int entityID) {return em.find(entityClass, entityID);}// Using the unchecked because JPA does not have a// em.getCriteriaBuilder().createQuery()<T> method@SuppressWarnings({ 'unchecked', 'rawtypes' })public List<T> findAll() {CriteriaQuery cq = em.getCriteriaBuilder().createQuery();cq.select(cq.from(entityClass));return em.createQuery(cq).getResultList();}// Using the unchecked because JPA does not have a// ery.getSingleResult()<T> method@SuppressWarnings('unchecked')protected T findOneResult(String namedQuery, Map<String, Object> parameters) {T result = null;try {Query query = em.createNamedQuery(namedQuery);// Method that will populate parameters if they are passed not null and emptyif (parameters != null && !parameters.isEmpty()) {populateQueryParameters(query, parameters);}result = (T) query.getSingleResult();} catch (Exception e) {System.out.println('Error while running query: ' + e.getMessage());e.printStackTrace();}return result;}private void populateQueryParameters(Query query, Map<String, Object> parameters) {for (Entry<String, Object> entry : parameters.entrySet()) {query.setParameter(entry.getKey(), entry.getValue());}} }package com.dao;import javax.ejb.Stateless;import com.model.Dog;@Stateless public class DogDAO extends GenericDAO<Dog> {public DogDAO() {super(Dog.class);} }package com.dao;import java.util.HashMap; import java.util.Map;import javax.ejb.Stateless;import com.model.User;@Stateless public class UserDAO extends GenericDAO<User> {public UserDAO() {super(User.class);}public User findUserByEmail(String email){Map<String, Object> parameters = new HashMap<String, Object>();parameters.put('email', email); return super.findOneResult(User.FIND_BY_EMAIL, parameters);} }關(guān)于上面的代碼:
- 我隱藏了一些警告,因?yàn)镴PA代碼尚未“理解”泛型。
- “ findOneResult”方法具有受保護(hù)的訪問權(quán)限,只是為了防止其他類進(jìn)行外部訪問。 正如我們?cè)赨serDAO中看到的那樣,此方法需要邏輯來填充參數(shù)。
- GenericDAO類具有完整的CRUD方法以及給定NamedQuery返回單個(gè)對(duì)象的方法。
- UserDAO類具有僅屬于該類的方法(findUserByEmail); 但是它通過繼承具有所有CRUD方法。 通過這種DAO模式,我們獲得了更靈活的代碼。
- DogDAO中沒有方法,只有CRUD方法。 您可以毫無問題地實(shí)現(xiàn)類中的任何方法。
- 可以使用一種方法“ entityManager.merge()”代替使用“保存”方法,而使用其他方法“更新”對(duì)象。 您將獲得相同的結(jié)果,但需要注意Cascade選項(xiàng)。
- 我沒有使用接口,因?yàn)镋JB 3.1允許我們擁有無接口的無狀態(tài)本地會(huì)話Bean。 如果使用的是較舊的EJB版本,則需要實(shí)現(xiàn)一個(gè)接口(如何在Fa?ades頁面上的這篇文章中看到如何使用接口實(shí)現(xiàn)EJB)。 我不會(huì)使用DAO /模型的接口進(jìn)行開發(fā),只是為了節(jié)省空間。 記住:“總是編程到一個(gè)接口”( 設(shè)計(jì)模式–策略 )。
- 如果使用JBoss 4.2,則可以使用org.jboss.annotation.ejb.LocalBinding或org.jboss.annotation.ejb.RemoteBinding注釋; 在此注釋中,您可以編寫將由EJB映射和引用的名稱。
商業(yè)–外墻
我將創(chuàng)建Fa?ades,它將成為View和DAO之間的“橋梁”。 在Fa?ade中,我們將保留所有業(yè)務(wù)規(guī)則,僅將DAO保留為“數(shù)據(jù)庫”功能/事務(wù),例如CRUD和查詢。
讓我們看看我們的類UserFacade和DogFacade將如何:
package com.facade;import java.util.List;import javax.ejb.Local;import com.model.Dog;@Local public interface DogFacade {public abstract void save(Dog dog);public abstract Dog update(Dog dog);public abstract void delete(Dog dog);public abstract Dog find(int entityID);public abstract List<Dog> findAll(); }package com.facade;import java.util.List;import javax.ejb.EJB; import javax.ejb.Stateless;import com.dao.DogDAO; import com.model.Dog;@Stateless public class DogFacadeImp implements DogFacade {@EJBprivate DogDAO dogDAO;@Overridepublic void save(Dog dog) {isDogWithAllData(dog);dogDAO.save(dog);}@Overridepublic Dog update(Dog dog) {isDogWithAllData(dog);return dogDAO.update(dog);}@Overridepublic void delete(Dog dog) {dogDAO.delete(dog);}@Overridepublic Dog find(int entityID) {return dogDAO.find(entityID);}@Overridepublic List<Dog> findAll() {return dogDAO.findAll();}private void isDogWithAllData(Dog dog){boolean hasError = false;if(dog == null){hasError = true;}if (dog.getName() == null || ''.equals(dog.getName().trim())){hasError = true;}if(dog.getWeight() <= 0){hasError = true;}if (hasError){throw new IllegalArgumentException('The dog is missing data. Check the name and weight, they should have value.');}} }package com.facade;import javax.ejb.Local;import com.model.User;@Local public interface UserFacade {public User findUserByEmail(String email); }package com.facade;import javax.ejb.EJB; import javax.ejb.Stateless;import com.dao.UserDAO; import com.model.User;@Stateless public class UserFacadeImp implements UserFacade {@EJBprivate UserDAO userDAO;public User findUserByEmail(String email) {return userDAO.findUserByEmail(email);} }關(guān)于上面的代碼:
- DogFacadeImp類完成了從視圖保護(hù)DogDAO的所有工作。 它可能具有業(yè)務(wù)規(guī)則,并且如果某些數(shù)據(jù)丟失或任何其他業(yè)務(wù)規(guī)則已被破壞,則避免訪問數(shù)據(jù)庫。
- UserFacade只有一種方法,因?yàn)樵谶@篇文章中我們將不會(huì)有一個(gè)User類。 如果視圖未在HttpSession中找到,則Bean將僅搜索用戶。
- 如果使用JBoss 4.2,則可以使用org.jboss.annotation.ejb.LocalBinding或org.jboss.annotation.ejb.RemoteBinding注釋; 在此注釋中,您可以編寫將由EJB映射和引用的名稱。
- 我在DogFacadeImp中進(jìn)行驗(yàn)證,以確保Dog僅具有有效數(shù)據(jù)。 請(qǐng)記住,每個(gè)人都可以向您發(fā)送無效數(shù)據(jù),并且您的視圖驗(yàn)證可能無法按您預(yù)期的那樣進(jìn)行。 您的應(yīng)用程序的數(shù)據(jù)非常重要,仔細(xì)檢查總是值得的。
接口使用@Local進(jìn)行注釋,但我記得您該注釋是可選的。 如果不寫@Local批注,則服務(wù)器將默認(rèn)假定您的EJB是本地的。
業(yè)務(wù)–數(shù)據(jù)源(按模塊)
我們還需要設(shè)置數(shù)據(jù)源。
最初,我嘗試通過遵循本教程http://community.jboss.org/wiki/JBossAS7-DatasourceConfigurationForPostgresql創(chuàng)建數(shù)據(jù)源(我確實(shí)像其他任何人一樣都遵循教程),但是在部署時(shí)使用了一些錯(cuò)誤EJB和JBoss找不到Postgres jar。
如果您使用的是JBoss 6或它下面的任何版本,則無需創(chuàng)建模塊。 只需將文件放在“ default / lib”文件夾中即可。 如果您對(duì)設(shè)置數(shù)據(jù)源有任何疑問,請(qǐng)?jiān)谙旅娴腏Boss 6或其他版本中顯示如何進(jìn)行操作: 使用JAAS和JSF進(jìn)行用戶登錄驗(yàn)證 。
讓我們創(chuàng)建Postgres模塊。 在JBoss 7內(nèi)部創(chuàng)建目錄: “ YOUR_JBOSS / modules / org / postgresql / main ”。 將jar復(fù)制到創(chuàng)建的目錄并創(chuàng)建一個(gè)名為“ module.xml”的文件; 將下面的代碼復(fù)制到“ module.xml”文件中:
<?xml version='1.0' encoding='UTF-8'?> <module xmlns='urn:jboss:module:1.0' name='org.postgresql'><resources><resource-root path='postgresql-9.1-901.jdbc4.jar'/></resources><dependencies><module name='javax.api'/></dependencies> </module>請(qǐng)注意,在“ module.xml”文件中,我們編寫了jar文件名,該名稱必須與Postgres jar文件名相同。
要?jiǎng)?chuàng)建MySQL模塊,請(qǐng)創(chuàng)建以下文件夾“ YOUR_JBOSS / modules / com / mysql / main ” 。 將jar復(fù)制到創(chuàng)建的目錄并創(chuàng)建一個(gè)名為“ module.xml”的文件; 將下面的代碼復(fù)制到“ module.xml”文件中:
<?xml version='1.0' encoding='UTF-8'?><!--~ JBoss copyrights~ http://community.jboss.org/wiki/DataSourceConfigurationInAS7--><module xmlns='urn:jboss:module:1.0' name='com.mysql'><resources><resource-root path='mysql-connector-java-5.1.15.jar'/></resources><dependencies><module name='javax.api'/></dependencies> </module>讓我們編輯文件“ YOUR_JBOSS / standalone / configuration / standalone.xml ”。 在鍵“ <datasources>”內(nèi),添加以下代碼:
<datasources><!-- Add this config: begin --><datasource jndi-name='CrudDS' pool-name='CrudDS_Pool' enabled='true' jta='true' use-java-context='true' use-ccm='true'><connection-url>jdbc:postgresql://localhost:5432/CrudDB</connection-url><driver-class>org.postgresql.Driver</driver-class><driver>postgresql-jdbc4</driver><pool><min-pool-size>2</min-pool-size><max-pool-size>20</max-pool-size><prefill>true</prefill><use-strict-min>false</use-strict-min><flush-strategy>FailingConnectionOnly</flush-strategy></pool><security><user-name>postgres</user-name><password>postgres</password></security><validation><check-valid-connection-sql>SELECT 1</check-valid-connection-sql><validate-on-match>false</validate-on-match><background-validation>false</background-validation><use-fast-fail>false</use-fast-fail></validation></datasource><!-- Add this config: end --><drivers><!-- Add this config: begin --><driver name='postgresql-jdbc4' module='org.postgresql'/><!-- Add this config: end --></drivers> 要使用MySQL配置數(shù)據(jù)源,請(qǐng)看這里:
http://community.jboss.org/wiki/DataSourceConfigurationInAS7
業(yè)務(wù)– XML配置
讓我們看看我們的persistence.xml將會(huì)如何(該文件必須在文件夾src / META-INF中):
<?xml version='1.0' encoding='UTF-8'?> <persistence version='1.0' xmlns='http://java.sun.com/xml/ns/persistence' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd'><persistence-unit name='CrudPU' transaction-type='JTA'><provider>org.hibernate.ejb.HibernatePersistence</provider><jta-data-source>java:/CrudDS</jta-data-source><properties><property name='hibernate.hbm2ddl.auto' value='update'/></properties></persistence-unit> </persistence>我們有一個(gè)非常簡(jiǎn)單的代碼; 它只是指向一個(gè)數(shù)據(jù)源,并帶有使用“ update”生成所有數(shù)據(jù)庫表的選項(xiàng)。
將EJB項(xiàng)目添加到JBoss。
在Postgres中創(chuàng)建數(shù)據(jù)庫并啟動(dòng)JBoss; 啟動(dòng)后,JPA將創(chuàng)建表。
在下面的圖片中查看JPA為我們創(chuàng)建的表/序列。
在WEB-INF文件夾中創(chuàng)建一個(gè)名為“ jboss-web.xml”的文件,并在其中編寫以下代碼:
<?xml version='1.0' encoding='UTF-8'?><jboss-web><!-- URL to access the web module --><context-root>CrudJSF</context-root><!-- Realm that will be used --><security-domain>java:/jaas/CrudJSFRealm</security-domain> </jboss-web>在上面的文件中,我們?cè)O(shè)置了應(yīng)用程序?qū)⑹褂玫念I(lǐng)域。 讓我們將用戶插入將通過JAAS進(jìn)行登錄的數(shù)據(jù)庫中(如果您想查看有關(guān)JAAS的更多詳細(xì)信息,可以在此處查看: 使用JAAS和JSF的用戶登錄驗(yàn)證 )。 我不會(huì)獲得JAAS詳細(xì)信息,因?yàn)槟梢哉业缴弦粋€(gè)鏈接中詳細(xì)介紹的每個(gè)步驟。
在下面的圖像中看到我在數(shù)據(jù)庫中手動(dòng)插入的數(shù)據(jù)(您應(yīng)該執(zhí)行相同的操作):
繼續(xù)本教程的第二部分 。
參考: uaiHebert博客上來自我們的JCG合作伙伴 Hebert Coelho的完整WebApplication JSF EJB JPA JAAS 。
翻譯自: https://www.javacodegeeks.com/2012/06/full-webapplication-jsf-ejb-jpa-jaas.html
總結(jié)
以上是生活随笔為你收集整理的完整的WebApplication JSF EJB JPA JAAS –第1部分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交行的活期富和余额宝区别
- 下一篇: 大额存单到期没有自动转存有没有什么影响?