本文使用的是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="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/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 = "http://localhost:8080/webServices/services/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.可以访问http://localhost:8080/webServices/EkkNameService?wsdl来查看接口描述
转载于:https://blog.51cto.com/florait/1600674