本文使用的是webservice开发接口的axis+rpc远程过程调用方式,基于soap通信协议(axis本质就是soap)。


  1. 导入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来查看接口描述