加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

webservice 初步学习

发布时间:2020-12-17 00:26:37 所属栏目:安全 来源:网络整理
导读:cxf 版本 2.7.2 服务端工程:CXFThirdServer IHelloWorld? package bean; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; @WebService public interface IHello

cxf 版本 2.7.2


服务端工程:CXFThirdServer

IHelloWorld?



package bean;

import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService
public interface IHelloWorld {
?? ?
?? ?@WebMethod
?? ?public @WebResult(name="returnStr")String sayHello(@WebParam(name="name")String name);
?? ?
?? ?@WebMethod
?? ?public @WebResult(name="returnUser")User sayHello2(@WebParam(name="name")String name,@WebParam(name="age")String age);
?? ?
?? ?@WebMethod
?? ?public @WebResult(name="returnList")List<User> sayHello3(@WebParam(name="name")String name,@WebParam(name="age")String age);

}

实现类HelloWorld:

package bean;

import java.util.ArrayList;
import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService
public class HelloWorld implements IHelloWorld {

?? ?@Override
?? ?@WebMethod
?? ?public @WebResult(name="name")String sayHello(@WebParam(name="name")String name){
?? ??? ?System.out.println("CXFThirdServer sayHello called...");
?? ??? ?return "Hello " + name;
?? ?}

?? ?@Override
?? ?@WebMethod
?? ?public @WebResult(name="returnUser")User sayHello2(@WebParam(name="name")String name,@WebParam(name="age")String age) {
?? ??? ?// TODO Auto-generated method stub
?? ??? ?System.out.println("CXFThirdServer sayHello2 called...");
?? ??? ?User user = new User();
?? ??? ?user.name = name;
?? ??? ?user.age = age;
?? ??? ?return user;
?? ?}
?? ?
?? ?@WebMethod
?? ?public @WebResult(name="returnList")List<User> sayHello3(@WebParam(name="name")String name,@WebParam(name="age")String age){
?? ??? ?List<User> returnList = new ArrayList<User>();
?? ??? ?for(int i =0; i < 3; i++){
?? ??? ??? ?User u = new User();
?? ??? ??? ?u.name = name+i;
?? ??? ??? ?u.age = age+i;
?? ??? ??? ?returnList.add(u);
?? ??? ?}
?? ??? ?return returnList;
?? ?}
?? ?

}

返回javabean:

User

package bean;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement(name="User")
@XmlAccessorType(value=XmlAccessType.FIELD)
public class User {
?? ?
?? ?public String name;
?? ?
?? ?public String age;

}

webservice 在网络上传输对象是用jaxb将对象序列化为xml。


main类 MainServer:

package main;

import javax.xml.ws.Endpoint;

import bean.HelloWorld;

public class MainServer {
?? ?
?? ?public static void main(String[] args){
?? ??? ?HelloWorld hello = new HelloWorld();
?? ????
?? ?}

}

//Endpoint.publish("http://localhost:9001/HelloWorld",hello);将hello发布成webservice到jdk内嵌的容器中;也可以发布到tomcat中,写配置文件cxfconfig.xml和web.xml,然后在tomcat的webapps文件夹下new一个文件,名称是工程名,我这里是CXFThirdServer,然后再把该工程的WEB-INFO拷贝到CXFThirdServer文件夹下,就算再tomcat里面部署好了,在浏览器里打开http://localhost:8080/CXFThirdServer/HelloWorld?wsdl,得到wsdl文件的内容,那么在tomcat里面该服务就算发布好了。


cxfconfig.xml

<beans xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:jaxws="http://cxf.apache.org/jaxws"
??? xsi:schemaLocation="
??????? http://www.springframework.org/schema/beans
??????? http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
??????? http://cxf.apache.org/jaxws
??????? http://cxf.apache.org/schemas/jaxws.xsd">
??? <import resource="classpath:META-INF/cxf/cxf.xml"/>
??? <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
??? <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

?? ?<jaxws:endpoint address="/HelloWorld"? implementor="bean.HelloWorld"><!--利用相对路径将服务发布到http://localhost:8080/CXFThirdServer/HelloWorld-->
?? ??? ?<jaxws:inInterceptors>
?? ??? ??? ?<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/><!--利用cxf的日志拦截器打印收到的soap消息和发送的soap消息-->
?? ??? ?</jaxws:inInterceptors>
?? ??? ?<jaxws:outInterceptors>
?? ??? ??? ?<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
?? ??? ?</jaxws:outInterceptors>
?? ?</jaxws:endpoint>
</beans>

web.xml:

?<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

?? ?<web-app> ?
?? ??? ?<!-- Spring Config Location -->
?? ???? <context-param>
?? ???????? <param-name>contextConfigLocation</param-name>
?? ???????? <param-value>/WEB-INF/cxfconfig.xml</param-value>
?? ???? </context-param>
?? ???? <!-- Spring ContextLoaderListener -->
?? ???? <listener>
?? ???????? <listener-class>
?? ???????????? org.springframework.web.context.ContextLoaderListener
?? ???????? </listener-class>
?? ???? </listener>
?? ???? <servlet>
?? ???????? <servlet-name>CXFServlet</servlet-name>
?? ???????? <display-name>CXF Servlet</display-name>
?? ???????? <servlet-class>
?? ???????????? org.apache.cxf.transport.servlet.CXFServlet
?? ???????? </servlet-class>
?? ???????? <load-on-startup>1</load-on-startup>
?? ???? </servlet>
?? ???? <!-- CXFServlet Mapping -->
?? ???? <servlet-mapping>
?? ???????? <servlet-name>CXFServlet</servlet-name>
?? ???????? <url-pattern>/*</url-pattern>
?? ???? </servlet-mapping>
??? </web-app>


下面是创建客户端工程:CXFThirdClient


利用wsdl2java命令生成对应的接口和javabean:wsdl2java -d F:cxftest http://localhost:8080/CXFThirdServer/HelloWorld?wsdl

将得到的IHelloWorld接口和User对象拷贝到CXFThirdClient工程下面的bean包中,

然后在main包中创建主类MainClient:

package main;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Future;

import javax.xml.namespace.QName;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Response;
import javax.xml.ws.Service;

import org.xml.sax.InputSource;

import bean.IHelloWorld;
import bean.User;

public class MainClient {

?? ?/**
?? ? * @param args
?? ? * @throws MalformedURLException
?? ? */
?? ?public static void main(String[] args) throws MalformedURLException {
?? ??? ?// TODO Auto-generated method stub
?? ??? ?QName serviceQName = new QName("http://bean/","HelloWorldService");//对应wsdl:service name="HelloWorldService"
?? ??? ?Service service = Service.create(new URL("http://localhost:8080/CXFThirdServer/HelloWorld?wsdl"),serviceQName);//

//GET http://localhost:8080/CXFThirdServer/HelloWorld?wsdl,对应URL地址http://localhost:8080/CXFThirdServer/HelloWorld?wsdl


?? ??? ?System.out.println("service = " + service);
?? ??? ?QName portQName = new QName("http://bean/","HelloWorldPort");
?? ??? ?sayHelloSync(service,portQName);
//?? ??? ?sayHelloAsync(service,portQName);
?? ?}
?? ?
?? ?private static void sayHelloSync(Service service,QName portQName){//同步方法调用sayHello
?? ??? ?
?? ??? ?/*IHelloWorld hello = service.getPort(portQName,IHelloWorld.class);
?? ??? ?System.out.println(hello.sayHello("text!"));*/
?? ??? ?
?? ??? ?
?? ?/*?? ?IHelloWorld hello = service.getPort(portQName,IHelloWorld.class);
?? ??? ?User user = hello.sayHello2("D Wade"," 31");
?? ??? ?System.out.println("name:"+user.getName()+" age:"+user.getAge());*/
?? ??? ?
?? ??? ?IHelloWorld hello = service.getPort(portQName,IHelloWorld.class);//对应<wsdl:port binding="tns:HelloWorldServiceSoapBinding" name="HelloWorldPort">
?? ??? ?List<User> returnList = hello.sayHello3("D Wade"," 31");//GET http://localhost:8080/CXFThirdServer/HelloWorld 报文体是发送过去的soap消息
?? ??? ?for(User user: returnList){
?? ??? ??? ?System.out.println("name:"+user.getName()+" age:"+user.getAge());
?? ??? ?}
?? ??? ?
?? ?}
?? ?
?? ?private static void sayHelloAsync(Service service,QName portQName){//利用回调方法异步调用sayHello
?? ??? ?final Dispatch<Source> dispatch = service.createDispatch(portQName,Source.class,Service.Mode.PAYLOAD);
?? ??? ?String payload = "<ns2:sayHello xmlns:ns2="http://bean/"><name>BBBBBBBBBBB!</name></ns2:sayHello>";
?? ??? ?final Source payloadMsg = new StreamSource(new StringReader(payload));

?? ??? ?System.out.println("msg = " + payloadMsg);
???
?? ??? ??? ??? ?Future f = dispatch.invokeAsync(payloadMsg,new AsyncHandler<Source>() {

//GET http://localhost:8080/CXFThirdServer/HelloWorld 报文体是发送过去的soap消息
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?@Override
?? ??? ??? ??? ??? ?public void handleResponse(Response<Source> res) {
?? ??? ??? ??? ??? ??? ?// TODO Auto-generated method stub
?? ??? ??? ??? ??? ??? ?try{
?? ??? ??? ??? ??? ??? ??? ?System.out.println("in handleResponse");
?? ??? ??? ??? ??? ??? ??? ?Source source = res.get();
?? ??? ??? ??? ??? ??? ??? ?Transformer transformer = TransformerFactory.newInstance().newTransformer();
?? ??? ??? ??? ??? ??? ??? ?transformer.transform(source,new StreamResult(System.out));
?? ??? ??? ??? ??? ??? ?}catch(Exception e){
?? ??? ??? ??? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?});

//?? ??? ?System.out.println("isDone = " + f.isDone());
?? ??? ?System.out.println("after dispatch.invokeAsync");
?? ?}

}


回调方法异步调用sayHello有些问题,有时候可以调用成功,有时候失败。debug了半天,发现dispatch.invokeAsync有时候发送过去的soap报文体丢失了,具体原因不明。


顺便提一句,soapui是模拟soap消息发送给webservice服务方的,貌似很好用!


再补个图先:


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读