web 项目集成福昕_项目学生:Web服务集成
web 項(xiàng)目集成福昕
這是Project Student的一部分。 其他帖子包括帶有Jersey的 Web服務(wù) 客戶(hù)端,帶有Jersey的 Web服務(wù)服務(wù)器 , 業(yè)務(wù)層 , 具有Spring數(shù)據(jù)的持久性和分片集成測(cè)試數(shù)據(jù) 。
早先,我們成功地針對(duì)持久性/業(yè)務(wù)層(使用嵌入式H2數(shù)據(jù)庫(kù))和REST服務(wù)器/客戶(hù)端層(使用Jetty服務(wù)器)運(yùn)行了集成測(cè)試。 現(xiàn)在是時(shí)候?qū)⑺袃?nèi)容編織在一起了。
幸運(yùn)的是,我們已經(jīng)準(zhǔn)備好所有代碼并進(jìn)行了測(cè)試。 現(xiàn)在我們要做的就是創(chuàng)建一些配置文件魔術(shù)。
局限性
- 用戶(hù)身份驗(yàn)證 –尚未進(jìn)行身份驗(yàn)證的工作。
- 加密 -尚未對(duì)通信進(jìn)行加密。
容器管理的數(shù)據(jù)源和JNDI
容器管理的數(shù)據(jù)源對(duì)許多開(kāi)發(fā)人員而言口碑不好,我不確定為什么。 可能與容器管理的持久性(CMP)混淆?
無(wú)論如何,容器管理的數(shù)據(jù)源背后的想法很簡(jiǎn)單。 您無(wú)需弄清楚如何在已部署的系統(tǒng)中維護(hù)數(shù)據(jù)庫(kù)連接參數(shù)-無(wú)需修改已部署的Web應(yīng)用程序(不安全)或從文件系統(tǒng)讀取文件(您可能無(wú)法訪(fǎng)問(wèn))等您只需將問(wèn)題交給維護(hù)Web服務(wù)器/應(yīng)用服務(wù)器的人員并通過(guò)JNDI檢索值。
Tomcat和Jetty需要在XML文件中進(jìn)行手動(dòng)配置。 像JBoss和GlassFish這樣的更高級(jí)的應(yīng)用服務(wù)器,使您可以通過(guò)漂亮的GUI配置數(shù)據(jù)源。 其實(shí)并不重要,因?yàn)槟恍枰獔?zhí)行一次。 Tomcat 7和Jetty的說(shuō)明 。
Tomcat的關(guān)鍵點(diǎn)是服務(wù)器庫(kù)位于$ CATALINA_HOME / lib下 ,并且可能不在您期望的位置。 例如,在Ubuntu中,它是/ usr / share / tomcat7 / lib ,而不是/ var / lib / tomcat7 / lib 。 其次,如果未從.war文件中提取META-INF / context.xml文件,則必須將其放在conf / Catalina / localhost / student-ws-webapp.xml (或任何已命名為.war文件的文件)下)。 后者會(huì)覆蓋前者,因此通常將.war文件設(shè)置為在開(kāi)發(fā)環(huán)境中運(yùn)行,然后在測(cè)試和生產(chǎn)環(huán)境中覆蓋配置。
META-INF / context.xml (Tomcat)
<?xml version="1.0" encoding="UTF-8"?> <Context><Resource name="jdbc/studentDS"auth="Container"type="javax.sql.DataSource"driverClassName="org.postgresql.Driver"url="jdbc:postgresql:student"username="student"password="student"maxActive="20"maxIdle="10"maxWait="-1"factory="org.apache.commons.dbcp.BasicDataSourceFactory" /></Context>值得注意的是,通過(guò)JNDI(作為java.lang.String)傳遞加密密鑰很簡(jiǎn)單。 對(duì)于修改已部署的Web應(yīng)用程序或訪(fǎng)問(wèn)服務(wù)器的文件系統(tǒng)的需求,這具有與前面討論的相同的好處。
(由于您希望您的實(shí)際加密密鑰既需要JNDI密鑰又需要基于文件系統(tǒng)的鹽,因此實(shí)現(xiàn)起來(lái)要復(fù)雜一些,但這在webapp的初始部署過(guò)程中很容易處理。)
JPA配置
我們的persistence.xml文件非常少。 我們通常需要兩個(gè)持久性單元,一個(gè)用于JTA事務(wù)(生產(chǎn)),一個(gè)用于非JTA事務(wù)(開(kāi)發(fā)和測(cè)試)。
META-INF / persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence 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"version="1.0"><persistence-unit name="studentPU-local"transaction-type="RESOURCE_LOCAL"><provider>org.hibernate.ejb.HibernatePersistence</provider><non-jta-data-source>jdbc/studentDS</non-jta-data-source></persistence-unit> </persistence>網(wǎng)頁(yè)配置
web.xml文件與集成測(cè)試中使用的文件幾乎相同。 關(guān)鍵區(qū)別在于,它為容器提供的數(shù)據(jù)源獲取資源引用。
WEB-INF / web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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-app_2_5.xsd"><display-name>Project Student Webservice</display-name><context-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></context-param><context-param><param-name>contextConfigLocation</param-name><param-value>com.invariantproperties.sandbox.student.config.PersistenceJpaConfigcom.invariantproperties.sandbox.student.config.BusinessApplicationContextcom.invariantproperties.sandbox.student.webservice.config.RestApplicationContext</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet><servlet-name>REST dispatcher</servlet-name><servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class><init-param><param-name>spring.profiles.active</param-name><param-value>test</param-value></init-param></servlet><servlet-mapping><servlet-name>REST dispatcher</servlet-name><url-pattern>/rest/*</url-pattern></servlet-mapping><resource-ref><description>Student Datasource</description><res-ref-name>jdbc/studentDS</res-ref-name><res-type>javax.sql.DataSource</res-type><res-auth>Container</res-auth></resource-ref> </web-app>彈簧配置
由于有兩個(gè)更改,因此持久層的Spring配置與以前大不相同。 從風(fēng)格上講,由于不再需要處理嵌入式數(shù)據(jù)庫(kù),因此可以使用標(biāo)準(zhǔn)配置文件而不是配置類(lèi)。
更為重要的更改是,我們已將所有數(shù)據(jù)源配置移至容器,并且可以從我們的spring配置中刪除它。 我們需要指向正確的數(shù)據(jù)源和持久性單元,僅此而已!
applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jee="http://www.springframework.org/schema/jee"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.2.xsdhttp://www.springframework.org/schema/data/jpahttp://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsdhttp://www.springframework.org/schema/jeehttp://www.springframework.org/schema/jee/spring-jee-3.0.xsd"><context:property-placeholder location="WEB-INF/database.properties" /><context:annotation-config /><!-- we use container-based datasource --><jee:jndi-lookup id="dataSource" jndi-name="${persistence.unit.dataSource}"expected-type="javax.sql.DataSource" /><bean name="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource" /><property name="persistenceUnitName" value="${persistence.unit.name}" /><property name="packagesToScan" value="${entitymanager.packages.to.scan}" /><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /></property></bean><bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" /><bean name="exceptionTranslation"class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /><tx:annotation-driven transaction-manager="transactionManager"proxy-target-class="false" /></beans>我們的屬性文件僅包含數(shù)據(jù)源的名稱(chēng),持久性單元名稱(chēng)以及包含JPA批注的要掃描的軟件包列表。
WEB-INF / database.properties
# jpa configuration entitymanager.packages.to.scan=com.invariantproperties.sandbox.student.domain persistence.unit.dataSource=java:comp/env/jdbc/studentDS persistence.unit.name=studentPU-local數(shù)據(jù)庫(kù)架構(gòu)和安全性
最后,集成測(cè)試可以使用Hibernate自動(dòng)創(chuàng)建功能,但是我們應(yīng)該始終在開(kāi)發(fā)和生產(chǎn)環(huán)境中顯式維護(hù)我們的架構(gòu)。 除了避免自動(dòng)化工具以意想不到的方式發(fā)揮作用帶來(lái)的潛在問(wèn)題之外,這還使我們能夠維護(hù)基礎(chǔ)架構(gòu)的價(jià)值。
在投入生產(chǎn)之前,編寫(xiě)和測(cè)試升級(jí)和降級(jí)腳本非常重要。 如果出現(xiàn)問(wèn)題,我們總是需要一種可以正常恢復(fù)的方法。
更重要的是,我們的數(shù)據(jù)庫(kù)架構(gòu)應(yīng)始終由Webapp之外的其他用戶(hù)擁有。 例如,Web應(yīng)用程序可以將“學(xué)生用戶(hù)”用于“學(xué)生所有者”創(chuàng)建的表。 這將防止使用SQL注入的攻擊者刪除或修改表。
-- -- for security this must run as student-owner, not student-user! ---- -- create an idempotent stored procedure that creates the initial database schema. -- create or replace function create_schema_0_0_2() returns void as $$ declareschema_version_rec record;schema_count int; begincreate table if not exists schema_version (schema_version varchar(20) not null);select count(*) into schema_count from schema_version;case schema_countwhen 0 then-- we just created tableinsert into schema_version(schema_version) values('0.0.2');when 1 then-- this is 'create' so we only need to make sure it's current version-- normally we accept either current version or immediately prior version.select * into strict schema_version_rec from schema_version;if schema_version_rec.schema_version '0.0.2' thenraise notice 'Unwilling to run updates - check prior version';exit;end if; elseraise notice 'Bad database - more than one schema versions defined!';exit;end case;-- create tables!create table if not exists test_run (test_run_pkey int primary key,uuid varchar(40) unique not null,creation_date timestamp not null,name varchar(80) not null,test_date timestamp not null,username varchar(40) not null);create table if not exists classroom (classroom_pkey int primary key,uuid varchar(40) unique not null,creation_date timestamp not null,test_run_pkey int references test_run(test_run_pkey),name varchar(80) not null);create table if not exists course (course_pkey int primary key,uuid varchar(40) unique not null,creation_date timestamp not null,test_run_pkey int references test_run(test_run_pkey),name varchar(80) not null);create table if not exists instructor (instructor_pkey int primary key,uuid varchar(40) unique not null,creation_date timestamp not null,test_run_pkey int references test_run(test_run_pkey),name varchar(80) not null,email varchar(200) unique not null);create table if not exists section (section_pkey int primary key,uuid varchar(40) unique not null,creation_date timestamp not null,test_run_pkey int references test_run(test_run_pkey),name varchar(80) not null);create table if not exists student (student_pkey int primary key,uuid varchar(40) unique not null,creation_date timestamp not null,test_run_pkey int references test_run(test_run_pkey),name varchar(80) not null,email varchar(200) unique not null);create table if not exists term (term_pkey int primary key,uuid varchar(40) unique not null,creation_date timestamp not null,test_run_pkey int references test_run(test_run_pkey),name varchar(80) not null);-- correction: need to define this!create sequence hibernate_sequence;-- make sure nobody can truncate our tablesrevoke truncate on classroom, course, instructor, section, student, term, test_run from public;-- grant CRUD privileges to student-user.grant select, insert, update, delete on classroom, course, instructor, section, student, term, test_run to student;grant usage on hibernate_sequence to student;return; end; $$ language plpgsql;-- create database schema select create_schema_0_0_2() is null;-- clean up drop function create_schema_0_0_2();整合測(cè)試
我們可以重復(fù)使用來(lái)自Web服務(wù)服務(wù)的集成測(cè)試,但是自1以來(lái),我還沒(méi)有將其復(fù)制到該項(xiàng)目中。我討厭復(fù)制代碼,最好將集成測(cè)試放入服務(wù)器和webapp都使用的單獨(dú)項(xiàng)目中,以及2)配置Jetty來(lái)提供JNDI值很容易,但是由于某種原因,記錄在案的類(lèi)拋出了異常,并且花很多時(shí)間進(jìn)行研究還不夠重要(此時(shí))。
源代碼
- 可從http://code.google.com/p/invariant-properties-blog/source/browse/student獲取源代碼。
更正
提供的模式忽略了創(chuàng)建新對(duì)象所需的“ hibernate_sequence”。 它必須由“學(xué)生”用戶(hù)定義并可讀。
翻譯自: https://www.javacodegeeks.com/2014/01/project-student-webservice-integration.html
web 項(xiàng)目集成福昕
總結(jié)
以上是生活随笔為你收集整理的web 项目集成福昕_项目学生:Web服务集成的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 房东 备案(房东备案单)
- 下一篇: linux查看dns配置(linux查看