利用反射调用webservice

来源:互联网 发布:淘宝大学认证 编辑:程序博客网 时间:2024/06/12 22:51

1、建立一个项目,专门用来发布服务,tomcat端口为8081,服务如下

1、webservice发布在tomcat上

 

2、点开链接wsdl

http://localhost:8081/SpringWebService/services/CommonService?wsdl

1、注意下面的serviceName 为CommonWSInterService

2、portNameCommonWSInterPort

3、发布的代码为

 

 

@WebService(targetNamespace="http://healerjean/")

publicinterfaceCommonWSInter{

 

publicStringsetMapParam(@XmlJavaTypeAdapter(MapAdapter.class)Map<String,Object>map);

    

    

}

 

4、实现的类为,最后返回Success

 

publicclassCommonWSImplimplementsCommonWSInter{

    

    /**

     * 测试传入的参数为map类型

     */

    @Override

    publicStringsetMapParam(Map<String,Object>map){

     

        System.out.println(map.toString());

        

        return"Success";

    }

    

}

 

2、生产客户端

 

3、设计WsDestEO,用来存储远程的webservice信息。制造这个list,这样选择pkWsDest,就可以选择要调用哪个服务

 

 

publicclassWsDestEO{

privateString pkWsDest;

 

privateString destName;

 

privateString isActive;

 

privateString wsdlAddr;

 

privateString namespace;

 

privateString serviceName;

 

privateString portName;

 

privateString objFacy;

 

privateString userCode;

 

privateString password;

 

privateString memo;

 

privateDate ts;

 

publicStringgetPkWsDest(){

return pkWsDest;

}

 

4、启动spring时候,加载上面的WsDestEO,这样只要spring容器一直存在,就能够使用上面的对象,也就是远程服务的参数。

    1、创建接口IWsService

 

publicinterfaceIWsService{

 

    publicWsDestInfogetWsDestInfoByKey(Stringkey);

    

}

2、实现接口WsServiceImp利用@PostConstructs,使spring启动即可加载(非常重要),使用list加载WsDestEO,这样可以加载多个,下面用来2个,第一个是真实使用的,第二个是为了试验效果

 

 

@Service

publicclassWsServiceImpimplementsIWsService{

    

    private List<WsDestInfo> wsDestInfos = new ArrayList<WsDestInfo>();

 

    /**

     * 初始化

     * @author :HealerJean:

     * @date :20171117下午4:44:48

     * @Description:

     * void

     */

    @SuppressWarnings("null")

    @PostConstruct

    publicvoidinit(){

 

        

        List<WsDestEO> wsDestEOs =newArrayList<WsDestEO>();

        WsDestEO wsDestEOOne =newWsDestEO(

                "trustee_healerjean", // pkWsDest

                "传输系统职业年金发送服务",

                "Y",         //选择是否可用,Y表示可用        "http://localhost:8081/SpringWebService/services/CommonService?wsdl",//

                 "http://healerjean/", // namespace

                "CommonWSInterService", // serviceName

                "CommonWSInterPort",// portName

                "com.hlj.client.ObjectFactory",// objFacy

                "dicp",    // userCode 这里用不到,随便写的,可以没有

                "dicp",// password 这里用不到,随便写的,可以没有

                " ",// memo 这里用不到,随便写的,可以没有

                newDate());

        WsDestEOwsDestEOTwo=newWsDestEO(

                "trustee_healerjean2",

                "传输系统职业年金发送服务",

                "N",                 "http://localhost:8080/SpringWebService/services/CommonService?wsdl",

                "http://healerjean/",

                "BusinessReceiveServices",

                "BusinessReceiveServicesPort",

                "com.reflect.client.ObjectFactory",

                "dicp",

                "dicp",

                " ",

                newDate());

        wsDestEOs.add(wsDestEOOne);

        for(WsDestEO wsDestEO : wsDestEOs){

            try{

                WsDestInfo wsDestInfo =newWsDestInfo();

                wsDestInfo.setWsDestEO(wsDestEO);

                wsDestInfo.init();// 初始化Dispatch对象

                wsDestInfos.add(wsDestInfo);

            }catch(Exception e){

                e.printStackTrace();

                // 打印后吃掉异常,保证程序正常启动

            }

        }

    }

    

    @Override

    publicWsDestInfogetWsDestInfoByKey(Stringkey){

        for(WsDestInfo wsDestInfo : wsDestInfos){

            if(wsDestInfo.getWsDestEO().getPkWsDest().equals(key)){

                return wsDestInfo;

            }

        }

        returnnull;

    }

    

}

 

 

5、设计发送的sender(非常重要)

1、getWsDestInfo通过pkWsDest可以找到WsDestInfo也就是服务信息

2、WsInvokeResult,为invoke反射之后,生成的,这里的代码会在send之后触发,具体看后文,WsDestInfo

3、接口里面的参数SetMapParam为发布服务里面的方法的名字,这里客户端import时候将它制造为一个类了,下面QName为方法名字,首字母要小写哦

4、WsResponse为反射调用远程服务的返回值里面的setReturnObjectsetMapParamResponse客户端的方法返回值

 

/**

* @author : HealerJean

* @date 20171117上午9:26:02

* @Description: 渠道调用受托的服务。用来交给受托进行代理人发来数据的业务校验

*/

@Component

publicclassSetMapParamSenderextendsWsSender<SetMapParam>{

 

    

    @Override

    publicWsDestInfogetWsDestInfo(){

 

        return wsService.getWsDestInfoByKey("trustee_healerjean");

    }

 

    @Override

    publicQNamegetOperationQName(){

        returnnewQName(getWsDestInfo().getWsDestEO().getNamespace(),"setMapParam");

    }

     

    

    @Override

    protectedWsResponsehandleInvokeResult(WsInvokeResultwsInvokeResult){

 

        WsResponse response =newWsResponse();

        if(YesOrNo.YES.getCode().equals(wsInvokeResult.getInvokeResult())){

            SetMapParamResponse setMapParamResponse =(SetMapParamResponse)wsInvokeResult.getReturnObject();

        /*    

String result = "01".equals(setMapParamResponse.getReturn()) ? YesOrNo.YES.getCode() : YesOrNo.NO.getCode();

            String respInfo = YesOrNo.YES.getCode().equals(result) ? "处理成功" : "处理失败:" + receiveDataOrFeedbackFromInteResponse.getReturn().getMsg();

            response.setRespResult(result);

            response.setRespInfo(respInfo);*/

            response.setReturnObject(setMapParamResponse);

 

        }else{

            response.setRespResult(YesOrNo.NO.getCode());

            response.setRespInfo("调用失败:"+wsInvokeResult.getInvokeInfo());

        }

        return response;

    }

 

}

 

5、(重中之重)4中抽象父类send方法就在这里面,invoke也在,并且有返回值,

 

publicabstractclassWsSender<T>{

         

    @Autowired

    protectedIWsService wsService;            

    @Autowired

    privateWsInvoker invoker;    

 

    privateString senderName;

    

    publicWsSender(){

        String simpleName =getClass().getSimpleName();

        senderName = simpleName.substring(0,1).toLowerCase()+ simpleName.substring(1);

    }

    

    /**

     * 默认为短类名首字母小写

     * @return

     */

    protectedStringgetSenderName(){

        return senderName;

    }

    

    publicabstractWsDestInfogetWsDestInfo();

    

    publicabstractQNamegetOperationQName();

    

    /**

     * 处理调用结果

     * @param wsInvokeResult 调用结果

     * @return

     */

    protectedWsResponsehandleInvokeResult(WsInvokeResultwsInvokeResult){

        // 默认情况下,简单返回调用结果

        WsResponse response =newWsResponse();

        response.setRespResult(wsInvokeResult.getInvokeResult());

        response.setRespInfo(wsInvokeResult.getInvokeInfo());

        response.setRespClob(wsInvokeResult.getInvokeClob());

        response.setReturnObject(wsInvokeResult.getReturnObject());

        return response;

    }

    

    @SuppressWarnings("unchecked")

    protectedJAXBElement<T>buildParam(Tparam){

        // 兼容重复的情况

        if(paraminstanceofJAXBElement<?>){

            return(JAXBElement<T>)param;

        }

        JAXBElement<T> element =newJAXBElement<T>(

                getOperationQName(),

                (Class<T>)param.getClass(),

                param);

        return element;

    }

    

    publicWsResponsesend(SendReasonVOreason,Tparam){

        JAXBElement<T> element =buildParam(param);

        returnsendIndependenceTrasaction(reason, element);

    }

    

    publicWsResponsesend(SendReasonVOreason,JAXBElement<?>param){

        returnsendIndependenceTrasaction(reason,param);

    }

 

    publicvoidsendAsyn(finalSendReasonVOreason,Tparam){

        finalJAXBElement<T> element =buildParam(param);

        // 此处简单启动异步线程处理,后期需要统一异步方式

        Runnable runnable =newRunnable(){

            @Override

            publicvoidrun(){

                sendIndependenceTrasaction(reason, element);

            }

        };

        Thread thread =newThread(runnable);

        thread.start();

    }

    

    privateWsResponsesendIndependenceTrasaction(finalSendReasonVOreason,finalJAXBElement<?>param){

                returnexecute(reason,param,getWsDestInfo());

    }

    

    privateWsResponseexecute(SendReasonVOreason,JAXBElement<?>param,WsDestInfodestInfo){

 

         

        

        String invokeResult =null;

        String invokeInfo =null;

        String invokeClob =null;

        Object returnObj =null;

        StringrespStatus="";

        try{

            Object obj = invoker.invoke(param,destInfo);

            if(obj instanceofJAXBElement){

                returnObj =((JAXBElement<?>) obj).getValue();

            }else{

                returnObj = obj;

            }

            respStatus = RespStatus.Normal.getCode();

            invokeResult = YesOrNo.YES.getCode();

            invokeInfo ="调用成功";

            // 正常响应报文,此报文不包含SOAP信封信息

            invokeClob =destInfo.marshal(obj);

        }catch(Exception e){

            e.printStackTrace();

            invokeResult = YesOrNo.NO.getCode();

            respStatus = RespStatus.Exception.getCode();

        }

         

     

            WsInvokeResult wsInvokeResult =newWsInvokeResult();

            wsInvokeResult.setInvokeResult(invokeResult);

            wsInvokeResult.setInvokeInfo(invokeInfo);

            wsInvokeResult.setInvokeClob(invokeClob);

            wsInvokeResult.setReturnObject(returnObj);

                

        

        // 处理调用结果

        WsResponse response =handleInvokeResult(wsInvokeResult);

        

        return response;

    }

}

 

6、创建测试的SetMapParamService,

1、下面有个MapConver的转化,比较恶心,为什么,因为这种方法产生的客户端没有适配器Adapter,而输入的map是客户端的com.hlj.client.MapConvertor,所以需要转化

 

@Component

publicclassSetMapParamService{

     

    

    @Autowired

    publicSetMapParamSender setMapParamSender;

    /**

     *

     * @author :HealerJean:

     * @date :20171117上午9:47:18

     * @Description: 调用受托的服务,让受托进行代理人发来数据的业务校验

     * @param map

     * @return

     * Result

     */

    publicStringreceiveOrBackSender(Map<String,Object>map){

        com.hlj.client.MapConvertor clientConvertor =new com.hlj.client.MapConvertor();

        com.reflect.mapconver.MapAdapter adapter =new com.reflect.mapconver.MapAdapter();

        try{

            com.reflect.mapconver.MapConvertor marshaled = adapter.marshal(map);

            List<com.reflect.mapconver.MapConvertor.MapEntry> entries = marshaled.getList();

                for(com.reflect.mapconver.MapConvertor.MapEntry mapEntry : entries){

                    com.hlj.client.MapEntry entry =new com.hlj.client.MapEntry();

                if(mapEntry.getKey().toUpperCase().equals("INSTITUTIONID")

                    || mapEntry.getKey().toUpperCase().equals("BUSINESSCODE")

                    || mapEntry.getKey().toUpperCase().equals("APPSERIONO")

                    || mapEntry.getKey().toUpperCase().equals("APPCODE")

                    || mapEntry.getKey().toUpperCase().equals("APPCODE")){

    // entry之间值交换

                    entry.setKey(mapEntry.getKey());

                    entry.setValue(mapEntry.getValue());

                    clientConvertor.getList().add(entry);

                }

            }    

        }catch(Exception e){

            e.printStackTrace();

        // 组装发送参数

        }

        /**

         * 发送的日志记录 Reason 用来存储报文的主键相关,我这里用不着

         */

        SendReasonVO reason =newSendReasonVO();

        

        SetMapParam setMapParam =newSetMapParam();

        setMapParam.setArg0(clientConvertor);

        

        WsResponse response = setMapParamSender.send(reason, setMapParam);

SetMapParamResponse setMapParamResponse =(SetMapParamResponse) response.getReturnObject();

        return setMapParamResponse.getReturn();

 

    }

 

}

 

7、执行测试

publicclassTestMain{

     

 

    publicstaticvoidmain(String[]args){

        ClassPathXmlApplicationContext context =newClassPathXmlApplicationContext(

                newString[]{"applicationContext.xml"});

        

SetMapParamService service=(SetMapParamService)context.getBean(SetMapParamService.class);

         

        

        Map<String,Object> map =newHashMap<String,Object>();

        map.put("INSTITUTIONID","INSTITUTIONID");

        map.put("BUSINESSCODE","2110");

        map.put("APPSERIONO","454564654165");

        map.put("APPCODE",0000);

        map.put("APPMSG","成功");

        String str = service.receiveOrBackSender(map);

 

        System.out.println(str);    

    }

}

 

8、测试成功

1、客户端

 

2、服务端

8、项目中间有改动的地方,请观察代码

 

原创粉丝点击