项目学生: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”。 它必须由“学生”用户定义并可读。

参考: 项目学生: Invariant Properties博客上的JCG合作伙伴 Bear Giles的Web服务集成 。

翻译自: https://www.javacodegeeks.com/2014/01/project-student-webservice-integration.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python爬虫requests实战_Python爬虫之requests库网络爬取简单实战

实例1&#xff1a;直接爬取网页 实例2 &#xff1a; 构造headers&#xff0c;突破访问限制&#xff0c;模拟浏览器爬取网页 实例3 &#xff1a; 分析请求参数&#xff0c;构造请求参数爬取所需网页 实例4&#xff1a; 爬取图片 实例5&#xff1a; 分析请求参数&#xff0c;构造…

某制冷设备制造厂商

某制冷设备制造厂商 该公司是一家以钣金加工&#xff0c;制冷设备制造、销售为主的公司&#xff0c;其产品广泛应用于高级宾馆、饭店及大型餐饮设施等。销售网点遍及日本、北美、欧洲及东南亚&#xff0c;产品深受世界各地用户的欢迎。 该公司原先使用的是TPICS生产管理系统&am…

原生JS实现的DOM操作笔记(草稿整理)

原生JS实现的DOM一系列操作参考&#xff1a; 原生JavaScript封装DOM库siblings: 原生JS-查找相邻的元素-siblings方法的实现addClass,removeClass,hasClass,toggleClass&#xff1a;原生js添加删除class原生js添加删除class 代码如下&#xff1a; var dom {/** 功能说明&…

简单的Gradle Java插件自定义

正如我在“ 用Gradle构建Java的初步了解”一文中所展示的那样&#xff0c;当人们使用Java插件并将文件和目录放置在该插件期望的位置时&#xff0c; Gradle尤其适用于构建Java应用程序的基础知识&#xff08;惯例-基于项目的布局 &#xff09;。 但是&#xff0c;并非总是有一种…

k8s 重点

这几个月参与了几场面试&#xff0c;设计了多道面试题&#xff0c;觉得可以综合考察应聘人对 kubernetes的掌握情况。在这里分享下&#xff0c;供应聘人自查以及其他面试官参考。 这些面试题的设计初衷并不是考察 kubernetes 的使用。这种笔者认为较为流于表面&#xff0c;因为…

python中print的用法_python中print用法

print用法 参考文档&#xff1a; https://blog.csdn.net/sinat_28576553/article/details/81154912 目录 一、print()函数概述 二、变量的输出 三、数据的格式化输出 3.1 %字符 3.2 最小字段宽度和精度 3.3 转换标志 3.4 格式字符归纳 四、换行与防止换行 一、print()函数概述 …

java 播放.pcm文件,java播发PCM文件

java播放PCM文件import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioSystem;import javax.sound.sa…

02 re模块

# re的工作是在python中执行正则表达式 import re# # find # result re.findall("\d", "baby的电话号是: 185123456789") # print(result) # # it re.finditer("\d", "baby123456789的电话号是: 185123456789") # for el in it: # …

网页中二维码识别规则

识别规则 这里采用的逻辑是截屏识别&#xff0c;当客户端发现用户在网页的img标签内进行长按操作时&#xff0c;会立刻截屏并且启动二维码识别算法。所以这里用于二维码识别的图片是截屏&#xff0c;而不是之前有人提到的img标签中的图片。 为什么要用截屏&#xff0c;这也是…

使用Mockito测试Spring组件

我认为&#xff0c;能够对弹簧组件进行单元测试而无需使用临时测试配置加载完整的弹簧上下文&#xff0c;这是一个很大的优势&#xff0c;因为它干净&#xff0c;易于维护&#xff0c;编写速度更快&#xff0c;更改平滑。 实现此目标的一种方法是使用Mockito并告诉他用Mocks &…

python数字转换_Python实现中文数字转换为阿拉伯数字的方法示例

本文实例讲述了Python实现中文数字转换为阿拉伯数字的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a; 一、需求 今天写了三千二百行代码。 今天写了3200行代码。 两行意思相同&#xff0c;只是表达方式不太能够&#xff0c;统一掉。 二、原理 数字的特征是 数字 …

LeetCode第14题:最长公共前缀

题目描述 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1: 输入: ["flower","flow","flight"] 输出: "fl" 示例 2: 输入: ["dog","racecar"…

臭名昭著的sun.misc.Unsafe解释

Java虚拟机的最大竞争对手可能是托管C&#xff03;等语言的Microsoft CLR 。 CLR允许编写不安全的代码作为低级编程的入口&#xff0c;这在JVM上很难实现。 如果您需要Java中的此类高级功能&#xff0c;则可能会被迫使用JNI &#xff0c;这需要您了解一些C并Swift导致代码紧密耦…

主从复制

五 主从复制 Replication(重要&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;) 5.1、介绍 基于主库二进制日志实时恢复到备库。 5.2、原理 5.2.1 主从复制的前提 &#xff08;1&#xff09;两台或两台以上数据库实例 &#xff08;2&#xff09;主库…

手机号正则表达 php,php 手机号码正则表达试程序代码_PHP教程

代码如下function funcMtel($str)//手机号码正则表达试{return (preg_match(“/(?:13d{1}|15[03689])d{8}$/”,$str))?true:false;}测试18678785887返回为false原因分析&#xff0c;查看了发现上面正则只能验证以13,15开头的&#xff0c;自然18开头的是不可以用的修改后代码如…

python输出格式控制_Python3.x那些事儿:[50]多种多样的输出格式

目前有两种方式来格式化输出格式&#xff0c;第一种就是自己动手来进行字符串的操作&#xff0c;虽然麻烦&#xff0c;但是都能实现。第二种方式就是使用str.format()函数。 string模块包含了一个Template类&#xff0c;这个类提供了把值替换成字符串的方法。 python提供把任意…

暑假第十五测

题解&#xff1a; 第一题&#xff1a; 20%枚举长度和每个子串&#xff0c;O&#xff08;len&#xff09;判断&#xff0c;随机情况复杂度可过 40%同样枚举长度&#xff0c;然后两个指针卡出区间&#xff0c;O(1)[或O(26)//可能可过&#xff1f;]判断 50%既然知道了40%的做法那…

扩展Spring Batch –步骤分区

在之前的几篇文章中&#xff0c;我们已经讨论了如何启动和运行Spring Batch。 现在&#xff0c;我们将开始讨论可用于扩展Spring Batch的一些策略。 本文将重点介绍如何对步骤进行分区&#xff0c;以使该步骤具有多个线程&#xff0c;每个线程并行处理一块数据。 如果您有大量…

zabbix磁盘的自动发现与磁盘指标监控

由于最近项目上需要对服务器监控进行规范化监控&#xff0c;再磁盘这块有几种方式 1.如果每台设备的磁盘是一样的 比如都有vda,vdb两块磁盘那么可以采用 1.1 每台客户端写脚本&#xff0c;服务端每台设备去加上监控项&#xff08;------最次的手段-------------&#xff09; 1.…

[代码笔记]VUE路由根据返回状态判断添加响应拦截器

//返回状态判断(添加响应拦截器)Axios.interceptors.response.use(res > {//对响应数据做些事if (res.data && !res.data.success) {Message({// 饿了么的消息弹窗组件,类似toastshowClose: true,message: res.data.error.message.message? res.data.error.messag…