- Server端项目结构
- Server端pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java1234.webservice</groupId> <artifactId>WS_Server</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-core</artifactId> <version>3.1.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.1.5</version> </dependency> <!--JDK11需要添加此依赖--> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-ri</artifactId> <version>2.3.1</version> </dependency> </dependencies> </project>
- Server端实体类
package com.cxf.entity; public class User { private Integer id; // 编号 private String userName; // 用户名 private String password; // 密码 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package com.cxf.entity; public class Role { private Integer id; // 编号 private String roleName; // 角色名称 public Role() { super(); // TODO Auto-generated constructor stub } public Role(Integer id, String roleName) { super(); this.id = id; this.roleName = roleName; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } }
package com.cxf.entity; import java.util.List; /** * 接口的返回值类型为Map时需要该中间实体来互转 * @author Administrator * */ public class MyRole { private String key; private List<Role> value; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public List<Role> getValue() { return value; } public void setValue(List<Role> value) { this.value = value; } }
- Server端接口
package com.cxf.webservice; import java.util.List; import java.util.Map; import javax.jws.WebService; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.cxf.adapter.MapAdapter; import com.cxf.entity.Role; import com.cxf.entity.User; @WebService public interface HelloWorld { // 返回值为String public String say(String str); // 返回值为List public List<Role> getRoleByUser(User user); // 返回值为Map-->需要自定义适配器:MapAdapter-->@XmlJavaTypeAdapter(MapAdapter.class) @XmlJavaTypeAdapter(MapAdapter.class) public Map<String,List<Role>> getRoles(); }
- Server端接口实现
package com.cxf.webservice.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.jws.WebService; import com.cxf.entity.Role; import com.cxf.entity.User; import com.cxf.webservice.HelloWorld; @WebService public class HelloWorldImpl implements HelloWorld{ public String say(String str) { return "Hello:"+str; } public List<Role> getRoleByUser(User user) { List<Role> roleList=new ArrayList<Role>(); roleList.add(new Role(1,"AAAA")); roleList.add(new Role(2,"BBBB")); return roleList; } public Map<String, List<Role>> getRoles() { Map<String,List<Role>> map=new HashMap<String,List<Role>>(); List<Role> roleList1=new ArrayList<Role>(); roleList1.add(new Role(1,"CCCC")); map.put("cccc", roleList1); List<Role> roleList2=new ArrayList<Role>(); roleList2.add(new Role(2,"DDDD")); map.put("dddd", roleList2); return map; } }
- Map类型返回值适配器
package com.cxf.adapter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.bind.annotation.adapters.XmlAdapter; import com.cxf.entity.MyRole; import com.cxf.entity.Role; public class MapAdapter extends XmlAdapter<MyRole[], Map<String,List<Role>>>{ /** * 适配转换 MyRole[] -> Map<String, List<Role>> */ @Override public Map<String, List<Role>> unmarshal(MyRole[] myRoles) throws Exception { Map<String, List<Role>> map=new HashMap<String,List<Role>>(); for(int i=0;i<myRoles.length;i++){ MyRole myRole=myRoles[i]; map.put(myRole.getKey(), myRole.getValue()); } return map; } /** * 适配转换 Map<String, List<Role>> -> MyRole[] */ @Override public MyRole[] marshal(Map<String, List<Role>> map) throws Exception { MyRole[] roles=new MyRole[map.size()]; Set<Map.Entry<String, List<Role>>> entries = map.entrySet(); Integer index = 0; for (Map.Entry<String, List<Role>> entry : entries) { roles[index]=new MyRole(); roles[index].setKey(entry.getKey()); roles[index].setValue(entry.getValue()); index++; } return roles; } }
- Server端自定义拦截器(调用接口方法前执行)
package com.cxf.interceptor; import java.util.List; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage> { public MyInterceptor() { super(Phase.PRE_INVOKE); // 调用接口方法前执行自定拦截器 } @SuppressWarnings("null") public void handleMessage(SoapMessage message) throws Fault { List<Header> headers=message.getHeaders(); if(headers==null && headers.size()==0){ throw new Fault(new IllegalArgumentException("没有Header,拦截器实施拦截")); } Header firstHeader=headers.get(0); Element ele=(Element) firstHeader.getObject(); NodeList uList=ele.getElementsByTagName("userName"); NodeList pList=ele.getElementsByTagName("password"); if(uList.getLength()!=1){ throw new Fault(new IllegalArgumentException("用户名格式不对")); } if(pList.getLength()!=1){ throw new Fault(new IllegalArgumentException("密码格式不对")); } String userName=uList.item(0).getTextContent(); String password=pList.item(0).getTextContent(); if(!userName.equals("cxf")||!password.equals("123456")){ throw new Fault(new IllegalArgumentException("用户名或者密码错误!")); } } }
- Server端启动类
package com.cxf.webservice.impl; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; import com.cxf.interceptor.MyInterceptor; import com.cxf.webservice.HelloWorld; public class Server { public static void main(String[] args) { System.out.println("web service start"); HelloWorld implementor=new HelloWorldImpl(); String address="http://localhost:8888/helloWorld"; // Endpoint.publish(address, implementor); // jdk实现 暴露webservice接口 JaxWsServerFactoryBean factoryBean=new JaxWsServerFactoryBean(); factoryBean.setAddress(address); // 设置暴露地址 factoryBean.setServiceClass(HelloWorld.class); // 接口类 factoryBean.setServiceBean(implementor); // 设置实现类 factoryBean.getInInterceptors().add(new LoggingInInterceptor()); // 添加in拦截器 日志拦截器 factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out拦截器 日志拦截器 factoryBean.getInInterceptors().add(new MyInterceptor()); factoryBean.create(); // 创建webservice接口 System.out.println("web service started"); } }
- 启动Server端
- Client端自动生成
https://pan.baidu.com/s/1wTK2ly-SJgZM99TyAdmPiw?pwd=hbn11.apache-cxf-3.1.5.zip解压后在环境变量添加bin路径 2.执行命令:wsdl2java -encoding utf-8 -d C:\Users\Administrator\Desktop\wsdl http://localhost:8888/helloWorld?wsdl 3.将C:\Users\Administrator\Desktop\wsdl路径下自动生成的java文件复制到Client端
- Client端pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java1234.webservice</groupId> <artifactId>WS_Client</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-core</artifactId> <version>3.1.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.1.5</version> </dependency> <!--JDK11需要添加此依赖--> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-ri</artifactId> <version>2.3.1</version> </dependency> </dependencies> </project>
- Client端自定义拦截器(发送SOAP消息时调用)
package com.cxf.interceptor; import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.w3c.dom.Document; import org.w3c.dom.Element; public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String userName; private String password; public AddHeaderInterceptor(String userName,String password) { super(Phase.PREPARE_SEND); // 准备发送SOAP消息的时候调用拦截器 this.userName=userName; this.password=password; } /** * 客户端拦截器和服务端拦截器对应,客户端拦截器向SoapMessage添加的参数可以在服务端拦截器获取到并进行校验 * 校验失败通过:throw new Fault(new IllegalArgumentException("没有Header,拦截器实施拦截"))抛出的异常在客户端控制台可见 * @param message * @throws Fault */ public void handleMessage(SoapMessage message) throws Fault { List<Header> headerList=message.getHeaders(); Document doc=DOMUtils.createDocument(); Element ele=doc.createElement("authHeader"); Element uElement=doc.createElement("userName"); uElement.setTextContent(userName); Element pElement=doc.createElement("password"); pElement.setTextContent(password); ele.appendChild(uElement); ele.appendChild(pElement); headerList.add(new Header(new QName("cxf"),ele)); } }
- Client端测试类
package com.cxf.webservice; import java.util.List; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import com.cxf.interceptor.AddHeaderInterceptor; public class Client { public static void main(String[] args) { HelloWorldService service=new HelloWorldService(); HelloWorld helloWorld=service.getHelloWorldPort(); org.apache.cxf.endpoint.Client client=ClientProxy.getClient(helloWorld); client.getOutInterceptors().add(new AddHeaderInterceptor("cxf","123456")); // 添加自定义拦截器 client.getInInterceptors().add(new LoggingInInterceptor()); // 添加In拦截器 日志拦截器 client.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加Out拦截器 日志拦截器 System.out.println(helloWorld.say("cxf")); List<Role> roles1=helloWorld.getRoleByUser(new User()); for(Role role:roles1){ System.out.println(role.getId()+","+role.getRoleName()); } // 返回值为Map,服务端需要适配转换 @XmlJavaTypeAdapter(MapAdapter.class)-->Map<String, List<Role>> -> MyRole[] List<MyRole> roles2 = helloWorld.getRoles().item; for (MyRole myRole : roles2) { String key = myRole.getKey(); List<Role> roles = myRole.getValue(); System.out.println(key+":"+roles.toString()); } } }
https://blog.csdn.net/caoli201314?type=blog