Web Service实践——Xfire的ws-security用户名和密码安全验证 - helloklzs - ITeye技术网站
三、服务器端
1、PasswordHandler类,继承自avax.security.auth.callback.CallbackHandler
package com.channelsoft.hr.wssecurity;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class PasswordHandler implements CallbackHandler {
@SuppressWarnings("unchecked")
private Map passwords = new HashMap();
@SuppressWarnings("unchecked")
public PasswordHandler() {
passwords.put("server", "serverpass");//服务器端记录的用户名和密码,可以有多个
}
public void handle(Callback[] callbacks) throws IOException,//回调接口方法
UnsupportedCallbackException {
System.out.println("Handling Password!");
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];//获取回调对象
String id = pc.getIdentifer();//获取用户名
System.out.println("id:"+id+" ,password:"+(String) passwords.get(id));
String validPw = (String)password.get(id);②-3:获取用户对应的正确密码
②-4:如果是明文密码直接进行判断
if(WSConstants.PASSWORD_TEXT.equals(callback.getPasswordType())){
String pw = callback.getPassword();
if(pw == null || !pw.equalsIgnoreCase(validPw)){
throw new WSSecurityException("password not match");
}
}else{
pc.setPassword((String) passwords.get(id));//如果是密码摘要,向回调设置正确的密码(明文密码)
}
}
2、service.xml
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>hrwebservice</name>
<namespace>com.channelsoft.hr</namespace>
<serviceClass>com.channelsoft.hr.webservice.DepartmentAndPersonInfo</serviceClass>
<implementationClass>com.channelsoft.hr.webservice.impl.DepartmentAndPersonInfoImpl</implementationClass>
<inHandlers>
<handler handlerClass="org.codehaus.xfire.util.dom.DOMInHandler" />
<bean
class="org.codehaus.xfire.security.wss4j.WSS4JInHandler" xmlns="">
<property name="properties">
<props>
<prop key="action">UsernameToken</prop>//使用用户名与密码进行安全验证
<prop key="passwordCallbackClass">
com.channelsoft.hr.wssecurity.PasswordHandler//回调类
</prop>
</props>
</property>
</bean>
</inHandlers>
</service>
</beans>
四、客户端
1、
1、PasswordHandler类,继承自avax.security.auth.callback.CallbackHandler
package com.channelsoft.hr.wssecurity;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class PasswordHandler implements CallbackHandler {
@SuppressWarnings("unchecked")
private Map passwords = new HashMap();
@SuppressWarnings("unchecked")
public PasswordHandler() {
passwords.put("server", "serverpass");//服务器端记录的用户名和密码,可以有多个
}
public void handle(Callback[] callbacks) throws IOException,//回调接口方法
UnsupportedCallbackException {
System.out.println("Handling Password!");
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];//获取回调对象
String id = pc.getIdentifer();//获取用户名
System.out.println("id:"+id+" ,password:"+(String) passwords.get(id));
String validPw = (String)password.get(id);②-3:获取用户对应的正确密码
②-4:如果是明文密码直接进行判断
if(WSConstants.PASSWORD_TEXT.equals(callback.getPasswordType())){
String pw = callback.getPassword();
if(pw == null || !pw.equalsIgnoreCase(validPw)){
throw new WSSecurityException("password not match");
}
}else{
pc.setPassword((String) passwords.get(id));//如果是密码摘要,向回调设置正确的密码(明文密码)
}
}
2、客户端调用
package hr;
import java.net.MalformedURLException;
import org.codehaus.xfire.client.Client;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.security.wss4j.WSS4JOutHandler;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.codehaus.xfire.transport.http.CommonsHttpMessageSender;
import org.codehaus.xfire.util.dom.DOMOutHandler;
import com.channelsoft.hr.webservice.DepartmentAndPersonInfo;
public class getHRInfo
{
public static void main(String args[])
{
String serviceURL = "http://localhost:8080/HRWebService/services/hrwebservice";
// 创建service对象
Service serviceModel = new ObjectServiceFactory().create(DepartmentAndPersonInfo.class);
XFireProxyFactory serviceFactory = new XFireProxyFactory();
try
{
// 获取服务对象
DepartmentAndPersonInfo service = (DepartmentAndPersonInfo) serviceFactory.create(serviceModel, serviceURL);
// 忽略http连接的超时时间,0为不设置超时时间,》=1为超时毫秒数
Client client = Client.getInstance(service);
client.setProperty(CommonsHttpMessageSender.HTTP_TIMEOUT, "0");
//发送授权信息
// client.addOutHandler(new ClientAuthenticationHandler("abcd","1234"));
// //WS-Security
WSS4JOutHandler wsOut = new WSS4JOutHandler();
String actions =WSHandlerConstants.USERNAME_TOKEN;
wsOut.setProperty(WSHandlerConstants.ACTION, actions);//动作
wsOut.setProperty(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PASSWORD_DIGEST);//密码类型
wsOut.setProperty(WSHandlerConstants.USER, "server"); //指定用户
wsOut.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordHandler.class.getName());//密码回调类
client.addOutHandler(new DOMOutHandler());
client.addOutHandler(wsOut);
// 调用服务
String hello = service.queryDepartmentInfo();
String hello2 = service.queryPersonnelInfo("", "", "");
System.out.println(hello);
System.out.println(hello2);
}
catch (MalformedURLException e)
{
System.out.println("错误!!!");
e.printStackTrace();
}
}
}
Web Service实践之——XFire实例
转自:http://www.javaeye.com/topic/195927
1、配置XFire运行环境:
在Tomcat下新建一个Web Applications,命名为stove,然后在其WEB-INF目录下新建一个web.xml文件,文件中输入:
Xml代码
<?xml version="1.0" encoding="GB2312">
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>XFireServlet</servlet-name>
<display-name>XFire Servlet</display-name>
<servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/servlet/XFireServlet/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
其中主要就是引入了XFireServlet,用以处理Web Service请求,并且负责提供Web Service的WSDL,如果你发布了一个名为BookService的WebService,则可以通过网址:
http://<服务器>[:端口]/<webapp名>/services/BookService
来访问这个WebService,并且通过地址:
http://<服务器>[:端口]/<webapp名>/services/BookService?WSDL 来得到这个WebService的WSDL信息。
2、开发最简单的WebService
建一个package:cn.com.pansky.webservice.xfire.study,在这个包下面新建一个接口:
Java代码
package cn.com.pansky.webservice.xfire.study;
public interface SayHiService{
public String sayHi(String name);
}
这个接口是告诉服务器你的WebService哪些方法可以被用户调用的。下面我们再来写一个SayHiService的实现类,以完成业务逻辑:
Java代码
package cn.com.pansky.webservice.xfire.study;
public class SayHiServiceImpl implements SayHiService{
public String sayHi(String name){
if(name==null){
return "连名字也不肯告诉我吗?";
}
return name+", 你吃了吗?没吃回家吃去吧。";
}
public String 不告诉你(){
return "我的名字不告诉你!";
}
} 这个类实现了sayHi方法,该方法是可以通过WebService调用访问到的。另外还实现了一个方法“不告诉你”,该方法因为没有在接口SayHiService中定义,所以不能被WebService调用到。
这个例子足够简单吧,就跟我们刚学Java时写的"Hello world"没什么两样。
到这里为止,我们做的跟平时的Java开发没啥区别,该如何来发布WebService呢?
3、把JAVA类发布为WebService:
在src目录下新建文件夹:META-INF/xfire,然后在该文件夹下新建一个XML文件:services.xml,文件内容如下:
Xml代码
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>SayHiService</name>
<namespace>http://cn.com.pansky/SayHiService</namespace>
<serviceClass>cn.com.pansky.webservice.xfire.study.SayHiService</serviceClass>
<implementationClass>cn.com.pansky.webservice.xfire.study.SayHiServiceImpl</implementationClass>
</service>
</beans>
这个文件定义一个WebService: SayHiService,并同时定义了接口和实现类。
好了,该建的文件基本建完了,现在想办法把src下的java文件编译成class,并复制到WEB-INF/classes目录下
4、启动Tomcat,测试WebService
如果Tomcat还没配置好,抽两分钟再配一下。再把Tomcat启动起来。
再打开浏览器,输入:
http://localhost/stove/services
,服务器返回的结果如下:
Available Services:
* SayHiService [wsdl]
Generated by XFire ( http://xfire.codehaus.org )
我们看到我们的WebService已经布署成功了,我们再看看它的WSDL信息:
这个文件跟我们用Axis生成的基本是一样的。
5、享受美味的时刻
注意:客户端使用WebService接口需要jar包(wsdl4j-1.6.1.jar和xfire-all-1.2.6.jar),缺少wsdl4j-1.6.1.jar时,会出现错误:The type javax.wsdl.Definition cannot be resolved. It is indirectly referenced from required .class files
WebService这道大餐算是烹制好了,现在是享用美餐的时候了。
我们写一个客户端吃掉这道大餐:
Java代码
package cn.com.pansky.webservice.xfire.study;
import java.net.MalformedURLException;
import java.util.Map;
import org.codehaus.xfire.client.Client;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.codehaus.xfire.transport.http.CommonsHttpMessageSender;
public class SayHiClient{
public static void main(String args[]) {
String serviceURL = "http://localhost/stove/services/SayHiService";
Service serviceModel = new ObjectServiceFactory().create(SayHiService.class,null,"http://cn.com.pansky/SayHiService",null);
XFireProxyFactory serviceFactory = new XFireProxyFactory();
try{
SayHiService service = (SayHiService) serviceFactory.create(serviceModel, serviceURL);
//忽略http连接的超时时间,0为不设置超时时间,》=1为超时毫秒数
Client client = Client.getInstance(service);
client.setProperty(CommonsHttpMessageSender.HTTP_TIMEOUT, "0");
String hello = service.sayHi("张山疯");
System.out.println("服务器对[张山疯] 的回答是:" + hello );
hello = service.sayHi(null);
System.out.println("服务器胡言乱语说:" + hello );
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
14. Object Relational Mapping (ORM) Data Access - Using sessionFactory getCurrentSession
Implementing DAOs based on plain Hibernate 3 API
Implementing DAOs based on plain Hibernate 3 API
Hibernate 3 has a feature called contextual sessions, wherein Hibernate itself manages one current Session per transaction. This is roughly equivalent to Spring’s synchronization of one Hibernate Session per transaction. A corresponding DAO implementation resembles the following example, based on the plain Hibernate API:
public class ProductDaoImpl implements ProductDao { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Collection loadProductsByCategory(String category) { return this.sessionFactory.getCurrentSession() .createQuery("from test.Product product where product.category=?") .setParameter(0, category) .list(); } }
This style is similar to that of the Hibernate reference documentation and examples, except for holding the SessionFactory in an instance variable. We strongly recommend such an instance-based setup over the old-school static HibernateUtil class from Hibernate’s CaveatEmptor sample application. (In general, do not keep any resources instatic variables unless absolutely necessary.)
The above DAO follows the dependency injection pattern: it fits nicely into a Spring IoC container, just as it would if coded against Spring’s HibernateTemplate. Of course, such a DAO can also be set up in plain Java (for example, in unit tests). Simply instantiate it and call setSessionFactory(..) with the desired factory reference. As a Spring bean definition, the DAO would resemble the following:
<beans> <bean id="myProductDao" class="product.ProductDaoImpl"> <property name="sessionFactory" ref="mySessionFactory"/> </bean> </beans>
The main advantage of this DAO style is that it depends on Hibernate API only; no import of any Spring class is required. This is of course appealing from a non-invasiveness perspective, and will no doubt feel more natural to Hibernate developers.
However, the DAO throws plain HibernateException (which is unchecked, so does not have to be declared or caught), which means that callers can only treat exceptions as generally fatal - unless they want to depend on Hibernate’s own exception hierarchy. Catching specific causes such as an optimistic locking failure is not possible without tying the caller to the implementation strategy. This trade off might be acceptable to applications that are strongly Hibernate-based and/or do not need any special exception treatment.
Fortunately, Spring’s LocalSessionFactoryBean supports Hibernate’s SessionFactory.getCurrentSession() method for any Spring transaction strategy, returning the current Spring-managed transactional Session even with HibernateTransactionManager. Of course, the standard behavior of that method remains the return of the current Sessionassociated with the ongoing JTA transaction, if any. This behavior applies regardless of whether you are using Spring’s JtaTransactionManager, EJB container managed transactions (CMTs), or JTA.
In summary: you can implement DAOs based on the plain Hibernate 3 API, while still being able to participate in Spring-managed transactions.
Spring 下hibernate多模块应用中多个hibernate.cfg.xml文件配置
Spring 下hibernate多模块应用中如何支持多个hibernate.cfg.xml文件配置呢?
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocations">
<list>
<value>classpath:hibernate.cfg.xml</value>
<value>classpath:hibernate-co.cfg.xml</value>
</list>
</property>
......
public void setConfigLocations(Resource[] configLocations)
- Set the locations of multiple Hibernate XML config files, for example as classpath resources "classpath:hibernate.cfg.xml,classpath:extension.cfg.xml".
-
Note: Can be omitted when all necessary properties and mapping resources are specified locally via this bean.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
- <property name="configLocations">
- <value>classpath:hibernate.cfg.xml,classpath:hibernate-co.cfg.xml
- </value></property>
......
3.4.3 理解数据仓库中的元数据 - 51CTO.COM
3.4.3 理解数据仓库中的元数据
信息包图同样也包含了数据仓库中的大部分元数据。元数据最普通的定义是“关于数据的数据”。正是有了元数据,才使得数据仓库的最终用户可以随心所欲地使用数据仓库,利用数据仓库进行各种管理决策模式的探讨。元数据是数据仓库的应用灵魂,可以说没有元数据就没有数据仓库。
1.元数据的类型
通常把元数据分为技术元数据(Technical Metadata)和业务元数据(Business Metadata)。
技术元数据是描述关于数据仓库技术细节的数据,这些元数据应用于开发、管理和维护数据仓库,它主要包含以下信息。
数据仓库结构的描述,包括仓库模式、视图、维、层次结构和导出数据的定义,以及数据集市的位置和内容;
业务系统、数据仓库和数据集市的体系结构和模式;
汇总用的算法,包括度量和维定义算法,数据粒度、主题领域、聚合、汇总和预定义的查询与报告;
由操作环境到数据仓库环境的映射,包括源数据和它们的内容、数据分割、数据提取、清理、转换规则和数据刷新规则及安全(用户授权和存取控制)。
业务元数据从业务角度描述了数据仓库中的数据,它提供了介于使用者和实际系统之间的语义层,使得不懂计算机技术的业务人员也能够“读懂”数据仓库中的数据。业务元数据主要包括以下信息:使用者的业务术语所表达的数据模型、对象名和属性名;访问数据的原则和数据的来源;系统所提供的分析方法及公式和报表的信息。
在信息打包过程中,需要用包图表示维度和类别还有它们之间的传递和映射关系,实际上这个操作就是在原业务系统的基础上创建了元数据。其中的维度、类别还有层次关系是属于典型的技术型元数据,而业务系统中与之对应的术语则属于业务元数据。比如前面的例子中提炼出的日期、区域、产品、客户年龄和客户状况等维度,实际销售、计划销售、预测销售、计划偏差和预测偏差等指标皆属于元数据。这些数据在以后的分析中起到了极为重要的作用。下面将对这些作用进行归纳。
2.元数据的作用
从元数据的类型和作用来看,元数据实际上是要解决何人在何时、何地为了什么原因及怎样使用数据仓库的问题。再具体化一点,元数据在数据仓库管理员的眼中是数据仓库中的包含了所有内容和过程的完整知识库和文档,而在最终用户(即数据分析人员)眼中,元数据则是数据仓库的信息地图。
数据分析员为了能有效地使用数据仓库环境,往往需要元数据的帮助。尤其是在数据分析员进行信息分析处理时,他们首先需要去查看元数据。元数据还涉及到数据从操作型环境到数据仓库环境中的映射。当数据从操作型环境进入数据仓库环境时,数据要经历一系列重大的转变,包含了数据的转化、过滤、汇总和结构改变等过程。数据仓库的元数据要能够及时跟踪这些转变,当数据分析员需要就数据的变化从数据仓库环境追溯到操作型环境中时,就要利用元数据来追踪这种转变。另外,由于数据仓库中的数据会存在很长一段时间,其间数据仓库往往可能会改变数据的结构。随着时间的流逝来跟踪数据结构的变化,是元数据另一个常见的使用功能。
元数据描述了数据的结构、内容、链和索引等项内容。在传统的数据库中,元数据是对数据库中各个对象的描述,数据库中的数据字典就是一种元数据。在关系数据库中,这种描述就是对数据库、表、列、观点和其他对象的定义;但在数据仓库中,元数据定义了数据仓库中的许多对象——表、列、查询、商业规则及数据仓库内部的数据转移。元数据是数据仓库的重要构件,是数据仓库的指示图。元数据在数据源抽取、数据仓库开发、商务分析、数据仓库服务和数据求精与重构工程等过程都有重要的作用,在图3-34中可以看到元数据在整个数据仓库开发和应用过程中的巨大影响。因此,设计一个描述能力强并且内容完善的元数据,对数据仓库进行有效地开发和管理具有决定性意义。
|
图3-34 元数据及其影响域
元数据拥有的巨大作用的发挥会在后面对数据仓库的分析中逐步体会到。这一节实际上通过信息打包技术建立起了数据仓库的概念模型,通过信息包图得到的星形结构或雪花形结构实际上为数据仓库建立起了逻辑模型。可以说,通过对主题和元数据的分析,应该能够对从现实世界到主观世界的过程(即概念模型的构建)有深刻的认识,而对逻辑模型还需要从事实和维度的角度进一步研究。
元数据管理是指标管理与知识管理的基石_233网校论文中心_管理其它相关论文_管理学论文
摘要:文章介绍了元数据管理建设情况,并基于元数据开展经营分析了系统的指标管理和知识管理。
关键词:元数据;指标;知识;管理
1 项目背景情况
吉林经营分析系统作为面向企业运营的统一数据信息平台,它的元数据管理重要性日益凸显出来,元数据管理贯穿经营分析系统构建、运行和维护的整个生命周期,是经营分析系统构建过程中重要的一环。同时,在数据仓库构建的整个过程中,如数据源分析、ETL过程、数据库结构、数据模型、业务应用主题的组织和前端展示等,均需要相应的元数据的有力支撑。
①元数据概念。元数据,从定义上讲,是关于数据的数据,或者说是关于数据的结构化数据。现在元数据研究的重点主要是网络环境下数据的描述与数据管理问题。经营分析系统元数据管理包括经营分析系统表结构、程序的处理规则、指标定义等技术元数据、业务元数据、管理元数据的管理。②集团公司试点。集团公司制定《元数据管理规范V1.0》,鉴于吉林移动具有良好数据质量、技术和业务基础,委托吉林移动根据规范进行元数据管理试点建设,通过实际的探索,总结建设过程中的经验和教训,为其他省的元数据建设及规范发展提供有益的参考。③省内需求。为更好地及时分析、查找、评估和解决省级经营分析系统各环节的数据质量问题,保证数据质量的稳定可靠,需要构建一套经营分析系统内部控制的管理体系,为数据质量管理工作提供强有力的系统支撑。
为了保证经营分析系统数据的一致性和可靠性,提高数据质量,要求构建以元数据管理为核心和基础的统一经营分析系统指标管理体系。
2 建设目标及要求
①元数据基础平台。吉林移动元数据试点项目的建设目标是构建一个体系结构独立,具备良好开放性和扩展性的元数据管理基础平台,具体要求如下:元数据管理系统的构建工作完全遵循集团公司CWM标准;提供元数据系统外部访问接口;在实施深度劈面,构建从源系统一直到OLAP分析、报表、KPI等方面的元数据管理系统,完成“数据流图”的构建过程。②指标管理体系。根据BOSS和BASS内数据指标的标准定义及处理过程描述,指标间依赖、关联辅承关系,以及这些指标的业务应用情景,建立一个完整的指标管理体系和指标库,具体要求如下:统一定义指标的业务术语、业务口径和相应的统计逻辑等信息,使之成为指标定义的字典;建立指标的层次结构,保证指标间的关联关系;业务交流、业务学习、知识传承的平台,加强对业务指标的理解,减少歧义,增加业务人员对业务系统的信任;业务管理、业务开发和系统管理的素材库和依据;加强对报表的管理,提高统计结果的重用度,提高生产效率;提高报表数据的准确性和一致性,满足表内、表间平衡关系和校验审核关系。
3 项目建设
①元数据基础平台。元数据管理基础平台是在MetaCenter的基础上进行本地化改造后完成,改造工作主要涉及MetaCenter的元数据获取,元数据展现,元数据外部访问接口3个方面。在元数据获取上,增加了DataStage,Essbase的自动元数据获取功能,以及对非自动获取的元数据提供一个批量的XML导人接口;在元数据展现上,增加影响分析及字段映射分析的图形界面;在元数据外部访问接口上,增加符合集团公司规范XMI及Corba IDL接口,以及供指标系统调用的Url API接口。②指标管理平台。吉林移动元数据管理在建设过程中严格遵循集团公司及CWM规范,并结合实际需求开发符合业务人员使用的指标管理平台,功能模块完整,结构清晰,系统间是一种松耦合的关系,符合扩展性及灵活性的建设要求。
4 效果与作用
①试点项目评审结果。吉林移动元数据管理系统在基于CWM模型的元数据管理方面,达到了国际移动通信领域的先进水平,具有重要的参考价值。②效果与作用。元数据管理系统已经在经营分析系统中起到了不可或缺的核心作用:知识中心,需求管理平台,数据对象的准确描述,全局视图;日常维护支持,分析数据对象的变更影响,集成监控;数据质量控制,监控数据统计过程;前端应用支持,提供数据对象的语义层。转贴
isnowfy/snownlp · 基于pathon 中文自然语言处理库
SnowNLP: Simplified Chinese Text Processing
SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英文的,于是写了一个方便处理中文的类库,并且和TextBlob不同的是,这里没有用NLTK,所有的算法都是自己实现的,并且自带了一些训练好的字典。注意本程序都是处理的unicode编码,所以使用时请自行decode成unicode。
Features
JDBCTemplate和HibernateTemplate事物源码解析 - - ITeye技术网站
由于项目中对批量的sql进行入库处理。所以打算用jdbcTemplate。在其他的增删改查中都是用hibernateTemplate。
在这里考虑到一个问题,就是当jdbcTemplate和hibernateTemplate结合用的时候,事务是怎么样的了?
经过测试:在一个方法中同时使用jdbcTemplate,和hibernateTemplate对数据进行增加操作。然后抛出异常。
发现事务是可以正常回滚的。但为什么可以这样了?看了下源码终于了解了一些。
<bean id="oaTM" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref bean="oaSessionFactory"/></property>
</bean>
总而言之。不管是使用jdbcTemplate或者是hibernateTemplate都是对jdbc的封装,说白了,对数据库的操作还是
使用connection,在回滚事务的时候还是调用了connection. Rollback方法来进行回滚的。
这一回想,在hibernate中有个sessionFactory. getCurrentSession()方法。调用的当前的线程session。
意思就是用当前的connection来操作数据。
在spring管理中有这么一个类来进行当前线程的数据绑定:TransactionSynchronizationManager
public abstract class TransactionSynchronizationManager
/* */ {
/* 77 */ private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class);
/* */
/* 80 */ private static final ThreadLocal<Map<Object, Object>> resources = newNamedThreadLocal("Transactional resources");
/* */
/* 83 */ private static final ThreadLocal<List<TransactionSynchronization>> synchronizations = newNamedThreadLocal("Transaction synchronizations");
/* */
/* 86 */ private static final ThreadLocal<String> currentTransactionName = newNamedThreadLocal("Current transaction name");
/* */
/* 89 */ private static final ThreadLocal<Boolean> currentTransactionReadOnly = newNamedThreadLocal("Current transaction read-only status");
/* */
/* 92 */ private static final ThreadLocal<Integer> currentTransactionIsolationLevel = newNamedThreadLocal("Current transaction isolation level");
/* */
/* 95 */ private static final ThreadLocal<Boolean> actualTransactionActive = new NamedThreadLocal("Actual transaction active");
在OpenEntityManagerInViewFilter,OpenSessionInViewInterceptor等需要获取当前线程对象的类中都用到了此类。
在使用hibernateTemplate可以使用hibernateTemplate.sessionFactory.getCurrentSession().connection获取当前的connection对象
在使用jdbcTemplate获取当前的connection对象的方法是:
public abstract class DataSourceUtils {
…
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
Assert.notNull(dataSource, "No DataSource specified");
//①首先尝试从事务同步管理器中获取数据连接
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder != null && (conHolder.hasConnection() ||
conHolder.isSynchronizedWithTransaction())) {
conHolder.requested();
if (!conHolder.hasConnection()) {
logger.debug("Fetching resumed JDBC Connection from DataSource");
conHolder.setConnection(dataSource.getConnection());
}
return conHolder.getConnection();
}
//②如果获取不到连接,则直接从数据源中获取连接
Connection con = dataSource.getConnection();
//③如果拥有事务上下文,则将连接绑定到事务上下文中
if (TransactionSynchronizationManager.isSynchronizationActive()) {
ConnectionHolder holderToUse = conHolder;
if (holderToUse == null) {
holderToUse = new ConnectionHolder(con);
}
else {holderToUse.setConnection(con);}
holderToUse.requested();
TransactionSynchronizationManager.registerSynchronization(
new ConnectionSynchronization(holderToUse, dataSource));
holderToUse.setSynchronizedWithTransaction(true);
if (holderToUse != conHolder) {
TransactionSynchronizationManager.bindResource(
dataSource, holderToUse);
}
}
return con;
}
…
}
当在同在方法中打印出这两个种方法获取的connection对象是同一对象时,基本上证明了在使用jdbcTemplate和hibernateTemplate的时候。
Eclipse Debug调试失败 hot code replace fail 几种情况
1、Tomcat部署了多个web应用程序,而所修改的类的名字在多个web应用中存在
2、修改了类的结构(如增加或删除类的方法,字段).
设置ear中war之间session共享 - gaohaiyang的专栏 - 博客频道 - CSDN.NET
设置ear中war之间session共享
由J2EE Servlet规范中,可以知道,正常情况下war之间session是彼此独立的,不可以共享的。
但是现在大部分J2EE服务器,都实现了EAR中war之间的session共享,如weblogic(>=9)、websphere。
设置weblogic的EAR中war之间session共享有下面两种方法:
1:设置EAR中的weblogic-application.xml文件,加入如下片段:
<wls:session-descriptor>
<wls:persistent-store-type>memory</wls:persistent-store-type>
<wls:sharing-enabled>true</wls:sharing-enabled>
</wls:session-descriptor>
整个weblogic-application.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:wls="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://www.bea.com/ns/weblogic/90http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<wls:weblogic-version>10.0</wls:weblogic-version>
<wls:context-root>testEARweb2</wls:context-root>
<wls:session-descriptor>
<wls:persistent-store-type>memory</wls:persistent-store-type>
<wls:sharing-enabled>true</wls:sharing-enabled>
</wls:session-descriptor>
</wls:weblogic-web-app>
2.设置需要共享session的war内的weblogic.xml文件,例如testEAR内有两个war,testEARweb1和testEARweb2,想让这两个war之间session共享,
则需要设置这两个war里面的weblogic.xml文件,同样,加入下面片段即可:
<wls:session-descriptor>
<wls:persistent-store-type>memory</wls:persistent-store-type>
<wls:sharing-enabled>true</wls:sharing-enabled>
</wls:session-descriptor>
设置后testEARweb1的weblogic.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:wls="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://www.bea.com/ns/weblogic/90http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<wls:weblogic-version>10.0</wls:weblogic-version>
<wls:context-root>testEARweb1</wls:context-root>
<wls:session-descriptor>
<wls:persistent-store-type>memory</wls:persistent-store-type>
<wls:sharing-enabled>true</wls:sharing-enabled>
</wls:session-descriptor>
</wls:weblogic-web-app>
testEARweb2的weblogic.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:wls="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://www.bea.com/ns/weblogic/90http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<wls:weblogic-version>10.0</wls:weblogic-version>
<wls:context-root>testEARweb2</wls:context-root>
<wls:session-descriptor>
<wls:persistent-store-type>memory</wls:persistent-store-type>
<wls:sharing-enabled>true</wls:sharing-enabled>
</wls:session-descriptor>
</wls:weblogic-web-app>
这样,EAR内的war之间就可以共享session了。
对于WAS,需要设置ibm-application-ext.xmi文件,
<applicationext:ApplicationExtension xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:applicationext="applicationext.xmi" xmlns:application="application.xmi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmi:id="Application_ID_Ext" sharedSessionContext="true">
其中sharedSessionContext="true",就是说明要开启共享session。
BIRT report viewer IE11 上预览不正常工作 及汉化
BIRT report viewer 在IE11上使用View Report In Web Viewer 是不能正常工作的,有两种办法:
1、删掉IE11
2、修改Eclipse.ini 增加
-Dorg.eclipse.swt.browser.DefaultType=mozilla
汉化包下载BabelLanguagePack-birt-zh_3.7.0.v20130724081219.zip
http://archive.eclipse.org/technology/babel/babel_language_packs/R0.11.0/indigo/indigo.php
解压覆盖features和plugins目录
How to benchmark BIRT report performance? - Stack Overflow
总结一下,大概有几点:
SQL执行计划,SQL跟踪调优
减少报表需要处理的数据,大量数据分页是不合适的
保持报表简洁,去掉无用的表格、图表
减少使用脚本,和数据源关联的脚本
For anyone else having problems with BIRT performance, here are a few more hints.
-
Profiling a BIRT report can be done using any Java profiler - write a simple Java test that runs your report and then profile that. As an example I use the unit tests from the SpudSoft BIRT Excel Emitters and run JProfiler from within Eclipse. The problem isn't with the difficulty in profiling it, it's in understanding the data produced :)
-
Scripts associated with DataSources can absolutely kill performance. Even a script that looks as though it should only have an impact up-front can really stop this thing. This is the biggest performance killer I've found (so big I rewrote quite a chunk of the Excel Emitters to make it unnecessary).
-
The emitter you use has an impact. If you are trying to narrow down performance problems always do separate Run and Render tasks so you can easily see where to concentrate your efforts.
-
Different emitter options can impact performance, particularly with the third party emitters (the SpudSoft emitters now have a few options for making large reports faster).
-
The difference between Fixed-Layout and Auto-Layout is significant, try both.
As I write this answer the question is getting close to 2 years old, so presumably you found a way around the problem. No one has offered a profiler for the entire process, so here are some ways of identifying bottle necks.
-
Start up time - About a minute can be spent here
- running a couple reports one after the other or starting a second after the first is running can help diagnosis issues.
-
SQL Query run time - Good solutions are mentioned in the question
- any SQL trace and performance testing will identify issues.
-
Building the report - This is where I notice the lions share of time being taken. Run a SQL trace while the report is being created. Even a relatively simple tables with lots of data can take around a minute to configure and display (HTML via apache tomcat) after the SQL trace indicates the query is done.
- simplify the report or create a clone with fewer graphs or tables run with and without pieces to see if any create a notable difference
- modify the query to bring back less records, less records are easier to display,
-
Delivery method PDF, Excel, HTML each can have different issues
- try the report to different formats
- if one is significantly greater, try different emitters.

