webservice
哈哈,今天是2009的最后一天,EF2009框架大部分工作基本告一段落。根据原先的设想完成的差不多了。
接下去的关键是如何解决打印问题。
结合网络上的一些讨论,最后觉得,还是自己开发一个ACTIVEX来打印比较好。
HZ2004用DELPHI7+REPORTBUILDER,离线笔录使用DELPHI2009+FASTREPORT,这两个各有优缺点,至于下阶段采用哪个开发还要研究一下。
用ACTIVEX打印报表,必须解决一个问题就是需要用到CLIENTDATASET来获取服务器的数据。
这个也只能沿用上面两个系统采用的方式就是通过webservice+XML的方式来解决。并且也有现成的代码可以参考。
目前的EF2009已经封装了接收json,返回Iqueryresoult的方式,再在上面扩展处理XML应该不是难事。
但是WEBSERVICE又遇到选择的问题,HZ2004和离线笔录都是采用AXIS,这个版本有点老,不知道能不能兼容,目前比较流行的是CXF,https://www6.software.ibm.com/developerworks/cn/education/java/j-cxf/section5.html,好处是能很好的兼容spring,所以到底使用AXIS还是CXF还是要再作考虑。
考虑到时间问题,决定还是采用AXIS开发WEBSERVICE。
--------------------------------------------------------------------------------------------
经过半天的折腾,总结如下:
1.AXIS采用的是1.4版本。导入相应的包,配置好WEB.XML和server-config.wsdd即可。
在配置过程中出现一个问题,当时struts的FilterDispatcher设置是*,导致所有对服务器的调用都跑到struts上去了,所以必须修改。配置如下:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 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"
version="2.4">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/configs/base-context.xml,
/WEB-INF/configs/service-context.xml,/WEB-INF/configs/view-context.xml,
/WEB-INF/configs/ws-context.xml</param-value>
</context-param>
<!--
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/configs/frame-base-context.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/configs/spring-hibernate-test.xml</param-value>
</context-param>
-->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/log4j.xml</param-value>
</context-param>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<!-- <url-pattern>*.action</url-pattern>-->
<url-pattern>*.action</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<!-- <url-pattern>*.action</url-pattern>-->
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<servlet>
<servlet-name>GetBeanServlet</servlet-name>
<servlet-class>com.hzjc.frame.common.GetBeanServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet>
<description>InitServlet For System which Load SystemParameterCode In JVM Memory In Using</description>
<display-name>InitServlet</display-name>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.hzjc.frame.servlet.InitServlet</servlet-class>
<load-on-startup>4</load-on-startup>
</servlet>
<!-- **********************axis**************************-->
<servlet id="Servlet_1086066211172">
<servlet-name>AdminServlet</servlet-name>
<display-name>Axis Admin Servlet</display-name>
<servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
<load-on-startup>12</load-on-startup>
</servlet>
<servlet id="Servlet_1086066211173">
<servlet-name>AxisServlet</servlet-name>
<display-name>Apache-Axis Servlet</display-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
<load-on-startup>13</load-on-startup>
</servlet>
<servlet id="Servlet_1086066211174">
<servlet-name>SOAPMonitorService</servlet-name>
<display-name>SOAP Monitor Service</display-name>
<servlet-class>org.apache.axis.monitor.SOAPMonitorService</servlet-class>
<init-param id="InitParam_1086066211175">
<param-name>SOAPMonitorPort</param-name>
<param-value>5001</param-value>
</init-param>
<load-on-startup>14</load-on-startup>
</servlet>
<servlet-mapping id="ServletMapping_1086066211176">
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping id="ServletMapping_1086066211177">
<servlet-name>SOAPMonitorService</servlet-name>
<url-pattern>/SOAPMonitor</url-pattern>
</servlet-mapping>
<servlet-mapping id="ServletMapping_1086066211179">
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping id="ServletMapping_1086066211180">
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/servlet/AdminServlet</url-pattern>
</servlet-mapping>
<servlet-mapping id="ServletMapping_1086066211181">
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<!--<error-page> -->
<!-- <error-code>404</error-code> -->
<!-- <location>/global/building.jsp</location> -->
<!--</error-page> -->
<!--<error-page> -->
<!-- <error-code>500</error-code> -->
<!-- <location>/global/error.jsp</location> -->
<!--</error-page> -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
server-config.wsdd
<?xml version="1.0" encoding="UTF-8"?>
<!--http://192.168.1.253:7010/hz2004axis//services/WSController?wsdl-->
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
<parameter name="adminPassword" value="admin"/>
<parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
<parameter name="sendXsiTypes" value="true"/>
<parameter name="sendMultiRefs" value="true"/>
<parameter name="sendXMLDeclaration" value="true"/>
<parameter name="axis.sendMinimizedElements" value="true"/>
<requestFlow>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="session"/>
</handler>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="request"/>
<parameter name="extension" value=".jwr"/>
</handler>
</requestFlow>
</globalConfiguration>
<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
<handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
<service name="AdminService" provider="java:MSG">
<parameter name="allowedMethods" value="AdminService"/>
<parameter name="enableRemoteAdmin" value="false"/>
<parameter name="className" value="org.apache.axis.utils.Admin"/>
<namespace>http://xml.apache.org/axis/wsdd/</namespace>
</service>
<service name="Version" provider="java:RPC">
<parameter name="allowedMethods" value="getVersion"/>
<parameter name="className" value="org.apache.axis.Version"/>
</service>
<service name="WSTest" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="className" value="com.hzjc.test.ws.WsServerTest"/>
</service>
<!--
<service name="WSLogin" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Request"/>
<parameter name="className" value="com.hzjc.wsstruts.WSLoginProxy"/>
</service>
<service name="WSController" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Request"/>
<parameter name="className" value="com.hzjc.wsstruts.WSControllerProxy"/>
</service>
-->
<transport name="http">
<requestFlow>
<handler type="URLMapper"/>
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
</requestFlow>
</transport>
<transport name="local">
<responseFlow>
<handler type="LocalResponder"/>
</responseFlow>
</transport>
</deployment>
2.AXIS和Spring的结合问题。
需要暴露成WEBSERVER的类从ServletEndpointSupport类继承,这样就可以直接加载SPRING中定义的BEAN.
import org.apache.axis.MessageContext;
import org.apache.axis.session.Session;
import org.apache.struts2.ServletActionContext;
import org.springframework.remoting.jaxrpc.ServletEndpointSupport;
import com.hzjc.frame.vo.VoUserInfo;
public class WsServerTest extends ServletEndpointSupport {
private IWsBean bean;
protected void onInit()
{
this.bean = (IWsBean) getWebApplicationContext().getBean("wsBean");
}
3.关于SESSION.
HZ2004是系统自己开发了一套SESSION管理机制,这样的管理机制比较负责,并且中间件如果是双机环境就比较麻烦。这里准备采用浏览器的SESSION管理。
浏览器的SESSION可以通过MessageContext来得到。
import org.apache.axis.MessageContext;
import org.apache.axis.session.Session;
import org.apache.struts2.ServletActionContext;
import org.springframework.remoting.jaxrpc.ServletEndpointSupport;
import com.hzjc.frame.vo.VoUserInfo;
public class WsServerTest extends ServletEndpointSupport {
public boolean Login(String user, String pass){
MessageContext mc = MessageContext.getCurrentContext();
Session session = mc.getSession();
session.set("user",user);
//保存用户名与口令
session.set("pass",pass);
return true;
}
public String getPassword(String user){
MessageContext mc = MessageContext.getCurrentContext();
Session session = mc.getSession();
if(user.equals(session.get("user")))
return (String)session.get("pass");
return null;
}
但是对于这样的调用,客户端必须做设置setMaintainSession,否则还是没效果。
public static void stubTest(){
try {
WsServerTestServiceLocator lsl = new WsServerTestServiceLocator();
lsl.setMaintainSession(true);
com.hzjc.test.ws.gen.WsServerTest login = lsl.getWSTest();
if(login.login("ld","haha")){
System.out.println("PWD:"+login.getPassword("ld"));
}
else{
System.out.println("Login failed.");
}
} catch (Exception e) {
// TODO: handle exception
}
}
4.DELPHI开发SERVICE客户端:
DELPHI7可以根据WSDL直接生成调用的类,生成方法:File->New->Other->WebService->WSDL Importer.
生成之后就可以进行使用,并且默认就是Maintain Session的。
5.AXIS直接开发SERVICE客户端:
可以通过AXIS直接调用WEBSERVICE:
try {
// int a = 100, b=60;
String name = "hongliang";
String endPoint = "http://127.0.0.1:8080/EF2009/services/WSTest";
Service service = new Service();
Call call = (Call)service.createCall();
call.setOperationName(new QName(endPoint,"SayHello"));
call.setTargetEndpointAddress(new URL(endPoint));
// String result = (String)call.invoke(new Object[]{new Integer(a),new Integer(b)});
String result = (String)call.invoke(new Object[]{name});
System.out.println("result is :"+result);
} catch (Exception e) {
e.printStackTrace();
}
这样的调用比较简单,但是无法maintain 客户端。
6.通过AXIS的STUB调用WEBSERVICE客户端
AXIS提供了wsdl2Java可以根据WSDL生成JAVA工具。
生成方法:在已经可以使用axis的java包的工程中,增加一个运行项。
直接运行就可以生成调用文件。
这些文件默认会在工程里面,刷新一下工程就可以 了,也可以生成到-o指定的路径下。
生成以后可以进行如下调用:
public static void stubTest(){
try {
WsServerTestServiceLocator lsl = new WsServerTestServiceLocator();
lsl.setMaintainSession(true);
com.hzjc.test.ws.gen.WsServerTest login = lsl.getWSTest();
if(login.login("ld","haha")){
System.out.println("PWD:"+login.getPassword("ld"));
}
else{
System.out.println("Login failed.");
}
} catch (Exception e) {
// TODO: handle exception
}
}
注意必须:lsl.setMaintainSession(true);才可以保存session
7.再谈SESSION
客户端如果用activex通过WEBSERVICE与服务器连,则会和IE浏览器的SESSION保持相同。也就是说,可以实现如下机制:
- 首先用纯WEB登录,实现用户的验证,并将验证后的信息(比如userInfo)保存在SESSION中。
- 用ACTIVEX通过WEBSERVICE调用服务器,服务器能获得SESSION中保存的userInfo信息。
LOGIN:
VoUserInfo userInfo = ((ISecurityService) _service).loginUser(this.getUserName(), this.getPassword());
ServletActionContext.getRequest().getSession().setAttribute("userInfo", userInfo);
WEBservice的被调用接口:
MessageContext mc = MessageContext.getCurrentContext();
Session session = mc.getSession();
VoUserInfo userInfo = (VoUserInfo)session.get("userInfo");
if (userInfo != null){
System.out.println(userInfo.getDlm());
}
其实通过MessageContext 也能得到HttpServletRequest
MessageContext mc = MessageContext.getCurrentContext();
Session session = mc.getSession();
HttpServletRequest req = (HttpServletRequest) mc
.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
Enumeration en = req.getSession().getAttributeNames();
while (en.hasMoreElements()){
System.out.println(en.nextElement());
}
VoUserInfo userInfo = (VoUserInfo)session.get("userInfo");
// VoUserInfo userInfo = (VoUserInfo) req.getSession().getAttribute("userInfo");
if (userInfo != null){
System.out.println(userInfo.getDlm());
}