1.所需jar
implementation group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxws', version: '3.3.4'
implementation group: 'org.apache.cxf', name: 'cxf-rt-transports-http', version: '3.3.4'
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.75'
implementation 'cn.hutool:hutool-all:5.6.5'
2.工程结构
3.cxf配置类
package com.example.webservice.demo.config;
import com.example.webservice.demo.service.IWebService;
import com.example.webservice.demo.service.impl.IWebServiceImpl;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class CxfConfig {
@Bean
public ServletRegistrationBean createDispatcherServlet() {
return new ServletRegistrationBean(new CXFServlet(),"/demo/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public IWebService demoService() {
return new IWebServiceImpl();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), demoService());
endpoint.publish("/api");
return endpoint;
}
}
4.Util类
package com.example.webservice.util;
import cn.hutool.log.StaticLog;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Properties;
@Component
public class Util {
private static String serverPort ;
private static final String URL = "/demo/api?wsdl";
@Value("${server.port}")
private String port;
@PostConstruct
public void setServerPort(){
this.serverPort= port;
StaticLog.info("port:"+this.serverPort);
}
/**
* 获取类路径
* @param className 类名
* @return
*/
public static String getClassPath(String className) {
String classUrl = null;
try {
Properties properties = new Properties();
// 使用ClassLoader加载properties配置文件生成对应的输入流
InputStream in = Util.class.getClassLoader().getResourceAsStream("config/config.properties");
// 使用properties对象加载输入流
properties.load(in);
//获取key对应的value值
classUrl = properties.getProperty(className);
} catch (Exception e) {
e.printStackTrace();
}
return classUrl;
}
/**
* 通过反射调用方法
* @param className
* @param methodName
* @param params
* @return
* @throws Exception
*/
public static Object invokeMethod(String className, String methodName, Map params) {
Object object = null;
//根据类名获取类路径
try {
String classUrl = Util.getClassPath(className);
Class<?> ownerClass = Class.forName(classUrl);
Object owner = ownerClass.newInstance();
Method method = ownerClass.getMethod(methodName, Map.class);
object = method.invoke(owner, params);
}catch (Exception e){
e.printStackTrace();
}
return object;
}
/**
* 创建动态客户端
* @return
*/
public static Client getClient(){
//创建动态客户端
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
String url = Util.getUrl()+URL;
StaticLog.info(url);
Client client = factory.createClient(url);
// 需要密码的情况需要加上用户名和密码
//client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(2000); //连接超时
httpClientPolicy.setAllowChunking(false); //取消块编码
httpClientPolicy.setReceiveTimeout(120000); //响应超时
conduit.setClient(httpClientPolicy);
//client.getOutInterceptors().addAll(interceptors);//设置拦截器
return client;
}
/**
* 获取当前服务的ip和端口
* @return
*/
public static String getUrl() {
InetAddress address = null;
try {
address = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return "http://"+address.getHostAddress() +":"+Util.serverPort;
}
}
5.接口类
package com.example.webservice.demo.service;
import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.ws.soap.MTOM;
import java.io.FileNotFoundException;
import java.io.IOException;
@WebService(name = "IWebService", targetNamespace = "http://service.demo.webservice.example.com")
@MTOM
public interface IWebService {
/**
* 普通字符串接口
*
* @param user
* @return
*/
@WebMethod
String sayHello(@WebParam(name = "user") String user);
/**
* json数据传输
*
* @param className
* @param methodName
* @param jsonData
* @return
*/
@WebMethod
String sendJsonData(@WebParam(name = "className") String className, @WebParam(name = "methodName") String methodName, @WebParam(name = "jsonData") String jsonData);
/**
* 文件上传(字节方式,使用小文件)
* @param bs
* @param fileName
* @return
*/
/* @WebMethod
String uploadFile(byte[] bs, String fileName);*/
/**
* 文件下载(字节方式)
* @param fileName
* @param type
* @return
*/
/*@WebMethod
byte[] downloadFile(String fileName, String type);*/
/**
* 文件上传(最大为128MB,超出会报:Text size limit (134217728) exceeded)
*
* @param dataHandler
* @param fileName
* @return
*/
@WebMethod
String uploadFile(@WebParam(name = "dataHandler")
//@XmlMimeType("application/octet-stream") 注解该字段为二进制流
@XmlMimeType(value = "*/*") //通用类型
DataHandler dataHandler, @WebParam(name = "fileName") String fileName) throws IOException;
@WebMethod
@WebResult
@XmlMimeType(value = "*/*")
DataHandler downloadFile(@WebParam(name = "fileName") String fileName) throws FileNotFoundException;
}
6.实现类
package com.example.webservice.demo.service.impl;
import com.alibaba.fastjson.JSON;
import com.example.webservice.demo.service.IWebService;
import com.example.webservice.util.Util;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.jws.WebService;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;
@WebService(serviceName = "IWebService", // 与接口中指定的name一致
targetNamespace = "http://service.demo.webservice.example.com", // 与接口中的命名空间一致,一般是接口的包名倒
endpointInterface = "com.example.webservice.demo.service.IWebService"// 接口地址
)
@Component
public class IWebServiceImpl implements IWebService {
@Override
public String sayHello(String user) {
return "hello "+user+",现在时间:"+"("+new Date()+")";
}
@Override
public String sendJsonData(String className, String methodName, String jsonData) {
Map<String, Object> map = JSON.parseObject(jsonData, Map.class);
Object result = Util.invokeMethod(className,methodName,map);
return result.toString();
}
@Override
public String uploadFile(DataHandler handler, String fileName) throws FileNotFoundException {
if (fileName != null && !"".equals(fileName)) {
// 根路径,在 resources/static/dwonload
String basePath = ResourceUtils.getURL("classpath:").getPath() + "static/dwonload/";
// uuid 生成文件名
// String uuid = String.valueOf(UUID.randomUUID());
// 新的文件名,使用uuid生成文件名
// fileName = uuid + "_" + fileName;
// 创建新的文件
File fileExist = new File(basePath);
// 文件夹不存在,则新建
if (!fileExist.exists()) {
fileExist.mkdirs();
}
// 获取文件对象
File file = new File(basePath, fileName);
if (handler != null) {
InputStream is = null;
FileOutputStream fos = null;
try {
is = handler.getInputStream();
fos = new FileOutputStream(file);
byte[] buff = new byte[1024 * 8];
int len = 0;
while ((len = is.read(buff)) > 0) {
fos.write(buff, 0, len);
}
} catch(FileNotFoundException e) {
return "fileNotFound";
} catch (Exception e) {
return "upload File failure";
} finally {
try {
if (fos != null) {
fos.flush();
fos.close();
}
if (is != null) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return "file absolute path:" + file.getAbsolutePath();
} else {
return "handler is null";
}
} else {
return "fileName is null";
}
}
@Override
public DataHandler downloadFile(String fileName) throws FileNotFoundException {
String basePath = ResourceUtils.getURL("classpath:").getPath() + "static/dwonload/";
DataHandler dataHandler = new DataHandler(
new FileDataSource(basePath+fileName){
public String getContentType() {
return "application/octet-stream";
}
}
);
return dataHandler;
}
}
7.客户端调用类
package com.example.webservice.demo.controller;
import com.alibaba.fastjson.JSON;
import com.example.webservice.util.Util;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/test")
public class WebClientController {
@GetMapping("/sayHello")
public String sayHello(){
String result = null;
Object[] objects;
try {
objects = Util.getClient().invoke("sayHello", "world");
result = objects[0].toString();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("返回数据:" + result);
return result;
}
@GetMapping("/sendJsonData")
public String sendJsonData(){
String result = null;
try {
//组装参数
Map<String,Object> map = new HashMap<>();
map.put("message","hello world");
System.out.println("json串:"+JSON.toJSONString(map));
// invoke("方法名",参数1,参数2,参数3....);
Object[] objects = Util.getClient().invoke("sendJsonData","WebClientController","test",JSON.toJSONString(map));
result = objects[0].toString();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("返回数据:" + result);
return result;
}
@GetMapping("/uploadFile")
public String uploadFile(){
String result = null;
Object[] objects;
try {
String path = "D:\\dbeaver.zip";
//这样就相当于构造了一个带文件路径的File了
DataHandler handler = new DataHandler(new FileDataSource(path));
objects = Util.getClient().invoke("uploadFile",handler, "dbeaver.zip");
result = objects[0].toString();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("返回数据:" + result);
return result;
}
@GetMapping("/downloadFile")
public String downloadFile(){
String result = "success";
InputStream is = null;
FileOutputStream fos = null;
try {
String path = "D:\\dbeaver.zip";
File file = new File(path);
Object[] objects = Util.getClient().invoke("downloadFile", "dbeaver.zip");
is = ((DataHandler) objects[0]).getInputStream();
fos = new FileOutputStream(file);
byte[] buff = new byte[1024 * 8];
int len = 0;
while ((len = is.read(buff)) > 0) {
fos.write(buff, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (fos != null) {
fos.flush();
fos.close();
}
if (is != null) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("返回数据:" + result);
return result;
}
public String test(Map<String, Object> map) {
System.out.println("获取message值:"+map.get("message"));
return "success";
}
}
8.下载链接
源码下载