本文使用的是webservice开发接口的axis+rpc远程过程调用方式,基于soap通信协议(axis本质就是soap)。
导入jar包
jaxrpc.jar
axis.jar
axis-ant.jar
wsdl4j.jar
commons-discovery-0.2.jar
commons-logging-1.0.4.jar
saaj.jar
dom4j.jar
2. 服务器端的开发:
首先编写一个类,这个类中的方法作为接口函数,供客户端调用。
注意这个类要继承ServletEndpointSupport
(原因:是为了使用其中的onInit方法。比如说,如果这个接口是service,需要调用dao层的方法操作数据库,用new的方法可以,但是无法保证service事务,所有用上下文方式获取dao。
protected void onInit() {
if(cormDao==null)
cormDao = (CormDao)WebAppContextUtil.getInstance().getBean("cormDao");
}
如果,不继承此类也可以,用如下方法获取dao也可以:
if(countTypeDao == null) {
WebApplicationContext context=ContextLoader.getCurrentWebApplicationContext();
countTypeDao = (CountTypeDao) context.getBean("countTypeDao");
}
)
先在web.xml文件中配置:
<!-- 定义AxisServlet-->
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<!-- 映射AxisServlet,使用通配符 -->
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
然后,在server-config.wsdd配置文件中进行配置:
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="" xmlns:java="">
<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder" /> <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" /> <!--服务名称和服务类 --> <service name="EkkNameService" provider="java:RPC"> <parameter name="allowedMethods" value="*" /><!--注意,如果只公开类中部分函数则:<parameter name="allowedMethods" value="queryInfo,queryProject,queryItem" />->
<parameter name="className" value="com.main.service.EkkNameService" /> </service> <transport name="http"> <requestFlow> <handler type="URLMapper" /> <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler" /><!-- 权限认证 -->
<handler name="IpAuthentication" type="java:com.ws.IpAuthenticationHandler" /> </requestFlow>
</transport> <transport name="local"> <responseFlow> <handler type="LocalResponder" /> </responseFlow> </transport></deployment>3.编写IpAuthenticationHandler类,来进行调用接口时的权限处理。(比如:校验此ip是否有权限调用此接口)
package com.ws;
import java.sql.Timestamp;
import java.util.Iterator;import java.util.Map;import java.util.Set;import javax.servlet.http.HttpServletRequest;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;import org.apache.axis.handlers.BasicHandler;import org.apache.axis.transport.http.HTTPConstants;import org.apache.commons.lang.StringUtils;import org.apache.log4j.Logger;import com.common.util.WebAppContextUtil;
/** * 根据Ip地址来进行权限过滤 * 这是ws处理权限的统一框架。所有ws调用都会到这里统一处理。 * @author Administrator * */public class IpAuthenticationHandler extends BasicHandler { private static final Logger logger = Logger.getLogger(IpAuthenticationHandler.class);private static final long serialVersionUID = 1L;
/** * 错误编号:权限错误——未申请权限 */ private static final String ERROR_CODE_HAS_NO_AUTH = "099"; /** * 操作类型:调用 */ private static final String OPER_TYPE_INVOKE = "1"; /** * 操作结果:成功 */ private static final String INVOKE_RESULT_SUCCESS = "0"; /** * 操作结果:失败 */ private static final String INVOKE_RESULT_FAIL = "9";/**
* 初始化 */ @Override public void init() { super.init(); }@Override
public void invoke(MessageContext msgContext) throws AxisFault { logger.info(msgContext.getSOAPActionURI()); logger.info(msgContext.getTargetService()); logger.info(msgContext.getOperation().getName()); logger.info(msgContext.getAllPropertyNames()); logger.info( msgContext.getUsername()); logger.info(msgContext.getPassword()); InterfaceInfo interfaceInfo = new InterfaceInfo(); HttpServletRequest request = (HttpServletRequest)msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); String remoteAddr = request.getRemoteAddr(); logger.debug("请求来自:"+remoteAddr); if(false){//此处写条件 //权限表中没有此ip logger.error("ip认证不通过"); //记错误日志。 saveLog(INVOKE_RESULT_FAIL,ERROR_CODE_HAS_NO_AUTH,"师徒调用未授权的接口。",remoteAddr,interfaceInfo); throw new AxisFault("Server.Unauthenticated","权限认证失败!", null,null); } } } 3.客户端调用接口: String endpointUrl = "/EkkNameService"; Service service = new Service(); Call call; try { call = (Call) service.createCall(); call.setTargetEndpointAddress(new java.net.URL(endpointUrl));// 参数分别为服务名称和方法名称
QName qName = new QName("EkkNameService", "getEkkNameByNameId"); call.setOperationName(qName);// 设定参数
call.addParameter("nameId",XMLType.XSD_STRING, ParameterMode.IN); call.setReturnType(XMLType.XSD_STRING);// 给参数赋值
Object[] objectArray = new Object[] {"12345"};String strResponse = (String) call.invoke(objectArray);
System.out.println("webservice结果:" + new String(strResponse)); } catch (Exception e) { throw new RuntimeException(e); }4.可以访问来查看接口描述