项目学生:Web服务集成
這是Project Student的一部分。 其他職位包括帶有Jersey的 Web服務 客戶端,帶有Jersey的 Web服務服務器 , 業務層 , 具有Spring數據的持久性和分片集成測試數據 。
早些時候,我們成功地針對持久性/業務層(使用嵌入式H2數據庫)和REST服務器/客戶端層(使用Jetty服務器)運行了集成測試。 現在是時候將所有內容編織在一起了。
幸運的是,我們已經準備好所有代碼并進行了測試。 現在我們要做的就是創建一些配置文件魔術。
局限性
- 用戶身份驗證 –尚未進行身份驗證的工作。
- 加密 –尚未對通信進行加密。
容器管理的數據源和JNDI
容器管理的數據源對許多開發人員而言聲譽不佳,我不確定為什么。 可能與容器管理的持久性(CMP)混淆?
無論如何,容器管理的數據源背后的想法很簡單。 您無需弄清楚如何在已部署的系統中維護數據庫連接參數-無需修改已部署的Web應用程序(不安全)或從文件系統讀取文件(您可能無法訪問)等您只需將問題交給維護Web服務器/應用服務器的人員,然后通過JNDI檢索值。
Tomcat和Jetty需要在XML文件中進行手動配置。 像JBoss和GlassFish這樣的更高級的應用服務器,使您可以通過漂亮的GUI配置數據源。 其實并不重要,因為您只需要執行一次。 Tomcat 7和Jetty的說明 。
Tomcat的關鍵點是服務器庫位于$ 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文件的文件)下)。 后者會覆蓋前者,因此通常將.war文件設置為在開發環境中運行,然后在測試和生產環境中覆蓋配置。
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>值得注意的是,通過JNDI(作為java.lang.String)傳遞加密密鑰很簡單。 對于修改已部署的Web應用程序或訪問服務器的文件系統的需求,這具有與前面討論的相同的好處。
(由于您希望實際的加密密鑰既需要JNDI密鑰又需要基于文件系統的鹽,因此實現起來要復雜一些,但這在webapp的初始部署過程中很容易處理。)
JPA配置
我們的persistence.xml文件非常少。 我們通常需要兩個持久性單元,一個用于JTA事務(生產),另一個用于非JTA事務(開發和測試)。
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>網頁配置
web.xml文件與集成測試中使用的文件幾乎相同。 關鍵區別在于,它為容器提供的數據源獲取資源引用。
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>彈簧配置
由于兩個更改,持久層的Spring配置與以前有很大不同。 從風格上講,由于不再需要處理嵌入式數據庫,因此可以使用標準配置文件而不是配置類。
更為重要的更改是,我們已將所有數據源配置移至容器,并且可以從我們的spring配置中刪除它。 我們需要指向正確的數據源和持久性單元,僅此而已!
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>我們的屬性文件僅包含數據源的名稱,持久性單元名稱以及包含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數據庫架構和安全性
最后,集成測試可以使用Hibernate自動創建功能,但是我們應該始終在開發和生產環境中明確維護我們的架構。 除了避免自動化工具以意想不到的方式發揮作用而帶來的潛在問題之外,這還使我們能夠維護基礎架構的價值。
在投入生產之前,編寫和測試升級和降級腳本非常重要。 如果出現問題,我們總是需要一種可以正常恢復的方法。
更重要的是,我們的數據庫架構應始終由Webapp之外的其他用戶擁有。 例如,Web應用程序可以對“學生所有者”創建的表使用“學生用戶”。 這將防止使用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();整合測試
我們可以重用來自Web服務服務的集成測試,但是自1以來,我還沒有將其復制到該項目中。我討厭復制代碼,最好將集成測試放入服務器和webapp都使用的單獨項目中,以及2)配置Jetty來提供JNDI值很容易,但是由于某種原因,記錄在案的類拋出了異常,并且花很多時間進行研究還不夠重要(此時)。
源代碼
- 可從http://code.google.com/p/invariant-properties-blog/source/browse/student獲取源代碼。
更正
提供的模式忽略了創建新對象所需的“ hibernate_sequence”。 它必須由“學生”用戶定義并可讀。
翻譯自: https://www.javacodegeeks.com/2014/01/project-student-webservice-integration.html
總結
以上是生活随笔為你收集整理的项目学生:Web服务集成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos怎么解决(香港ddos解决方案)
- 下一篇: 域名接入备案需要多久(域名接入备案)