增加一个cxf

This commit is contained in:
Xiong Neng 2018-06-15 18:40:21 +08:00
parent f8e958fa71
commit 26e4227ace
15 changed files with 655 additions and 0 deletions

14
springboot-cxf/.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
# 此为注释– 将被Git 忽略
# /结尾表示是目录,忽略目录和目录下的所有件
# /开头表示根目录,否则是.gitignore的相对目录
# !开头表示反选
.idea/
target/
*.iml
*.ipr
*.iws
*.log
.svn/
.project
rebel.xml
.rebel-remote.xml.*

20
springboot-cxf/LICENSE Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 Xiong Neng
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

29
springboot-cxf/README.md Normal file
View File

@ -0,0 +1,29 @@
## 实现WebService
利用Apache CXF实现WebService
启动之后wsdl访问链接<http://localhost:8092/services/CommonService?wsdl>
## 客户端动态代理调用
这个在单元测试类ApplicationTests中有演示
## 生产客户端代码
apache的wsdl2java工具使用`-autoNameResolution`自动处理
```
wsdl2java -autoNameResolution http://xxx?wsdl
```
JDK自带的工具
```
wsimport -p com.enzhico.land.client -keep http://xxx?wsdl -s d:/ws -B-XautoNameResolution
```
## 许可证
Copyright (c) 2018 Xiong Neng
基于 MIT 协议发布: <http://www.opensource.org/licenses/MIT>

106
springboot-cxf/pom.xml Normal file
View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<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.xncoding</groupId>
<artifactId>springboot-cxf</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-restful</name>
<description>CXF实现WebService</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- CXF webservice -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.2.4</version>
</dependency>
<!-- CXF webservice -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<!--<proc>none</proc>-->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>

72
springboot-cxf/run.sh Normal file
View File

@ -0,0 +1,72 @@
#!/bin/bash
# 项目自动更新脚本
# 先clone相应的分支下来
# git clone ssh://git@120.24.173.142:7999/xxx.git
# 远程调试启动:
# nohup java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 &
function start {
profile="$1"
echo "启动环境profile=${profile}"
jarfile=$(ls target/*.jar)
if [[ "$?" == "0" ]]; then
stop $profile $jarfile
fi
branch=$(git branch |awk '{print $2}')
git pull origin ${branch}
echo "更新完代码开始重新打包"
mvn clean && mvn clean && mvn package -DskipTests=true
if [[ "$?" != "0" ]]; then
echo "编译出错,退出!"
exit 1
fi
echo "nohup java -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 &"
nohup java -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 &
echo "启动应用中,请查看日志文件..."
}
function stop {
profile="$1"
jarfile="$2"
ps aux | grep "${jarfile}" | grep "spring.profiles.active=${profile}" | grep -v grep > /dev/null
if [[ "$?" == "0" ]]; then
echo "该应用还在跑,我先停了它"
pid=$(ps aux | grep "${jarfile}" | grep "spring.profiles.active=${profile}" | grep -v grep |awk '{print $2}')
if [[ "$pid" != "" ]]; then
kill -9 $pid
fi
echo "停止应用成功..."
fi
}
if [[ "$1" == "start" ]]; then
if [[ "$#" < 2 ]]; then
echo "请输入正确参数:./epay.sh start {profile}"
exit 1
fi
profile="$2"
if [[ "$profile" != "dev" && "$profile" != "test" && "$profile" != "show" && "$profile" != "production" ]]; then
echo "参数错误请输入正确的profile参数使用方法"
echo "./epay.sh start {profile} ==> 启动应用,{profile}取值dev|test|show|production"
exit 1
fi
start "${profile}"
elif [[ "$1" == "stop" ]]; then
if [[ "$#" < 2 ]]; then
echo "请输入正确参数:./epay.sh stop {profile}"
exit 1
fi
profile="$2"
if [[ "$profile" != "dev" && "$profile" != "test" && "$profile" != "show" && "$profile" != "production" ]]; then
echo "参数错误请输入正确的profile参数使用方法"
echo "./epay.sh stop {profile} ==> 停止应用,{profile}取值dev|test|show|production"
exit 1
fi
jarfile=$(ls target/*.jar)
stop $profile $jarfile
else
echo "参数错误,使用方法:{}参数是必填的,[]参数可选"
echo "./epay.sh start {profile} ==> 启动应用,{profile}取值dev|test|show|production"
echo "./epay.sh stop {profile} ==> 停止应用,{profile}取值dev|test|show|production"
exit 1
fi

View File

@ -0,0 +1,12 @@
package com.xncoding.webservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,38 @@
package com.xncoding.webservice.config;
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import com.xncoding.webservice.service.ICommonService;
import org.springframework.context.annotation.Configuration;
/**
* 默认服务在 Host:port/services/*** 路径下
* 这里相当于把Commonservice接口发布在了路径/services/CommonService下
* wsdl文档路径为http://localhost:8080/services/CommonService?wsdl
*
* @author XiongNeng
* @version 1.0
* @since 2018/6/15
*/
@Configuration
public class CxfConfig {
@Autowired
private Bus bus;
@Autowired
ICommonService commonService;
/**
* JAX-WS
**/
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, commonService);
endpoint.publish("/CommonService");
return endpoint;
}
}

View File

@ -0,0 +1,60 @@
package com.xncoding.webservice.model;
/**
* 基础返回类
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/7
*/
public class BaseResponse<T> {
/**
* 是否成功
*/
private boolean success;
/**
* 说明
*/
private String msg;
/**
* 返回数据
*/
private T data;
public BaseResponse() {
}
public BaseResponse(boolean success, String msg, T data) {
this.success = success;
this.msg = msg;
this.data = data;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

View File

@ -0,0 +1,47 @@
package com.xncoding.webservice.model;
/**
* 用户
*
* @author XiongNeng
* @version 1.0
* @since 2018/3/4
*/
public class User {
private Long id;
private String name;
private Integer age;
public User() {
}
public User(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}

View File

@ -0,0 +1,27 @@
package com.xncoding.webservice.service;
import com.xncoding.webservice.model.User;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* ICommonService
*
* @author XiongNeng
* @version 1.0
* @since 2018/6/15
*/
@WebService(name = "CommonService", // 暴露服务名称
targetNamespace = "http://model.webservice.xncoding.com/"// 命名空间,一般是接口的包名倒序
)
public interface ICommonService {
@WebMethod
// @WebResult(name = "String", targetNamespace = "")
public String sayHello(@WebParam(name = "userName") String name);
@WebMethod
// @WebResult(name = "String", targetNamespace = "")
public User getUser(@WebParam(name = "userName") String name);
}

View File

@ -0,0 +1,32 @@
package com.xncoding.webservice.service.impl;
import com.xncoding.webservice.model.User;
import com.xncoding.webservice.service.ICommonService;
import org.springframework.stereotype.Component;
import javax.jws.WebService;
/**
* CommonServiceImpl
*
* @author XiongNeng
* @version 1.0
* @since 2018/6/15
*/
@WebService(serviceName = "CommonService", // 与接口中指定的name一致
targetNamespace = "http://model.webservice.xncoding.com/", // 与接口中的命名空间一致,一般是接口的包名倒
endpointInterface = "com.xncoding.webservice.service.ICommonService"// 接口地址
)
@Component
public class CommonServiceImpl implements ICommonService {
@Override
public String sayHello(String name) {
return "Hello ," + name;
}
@Override
public User getUser(String name) {
return new User(1000L, name, 23);
}
}

View File

@ -0,0 +1,45 @@
package com.xncoding.webservice.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* JacksonUtil
*
* @author XiongNeng
* @version 1.0
* @since 2018/3/4
*/
public class JacksonUtil {
private static ObjectMapper mapper = new ObjectMapper();
public static String bean2Json(Object obj) {
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
// public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
// try {
// return mapper.readValue(jsonStr, objClass);
// } catch (IOException e) {
// e.printStackTrace();
// return null;
// }
// }
public static <T> T json2Bean(String jsonStr, TypeReference<T> typeReference) {
try {
return mapper.readValue(jsonStr, typeReference);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,33 @@
##########################################################
################## 所有profile共有的配置 #################
##########################################################
################### 项目启动端口 ###################
server.port: 8092
################### spring配置 ###################
spring:
profiles:
active: dev
cxf:
path: /services # 替换默认的/services路径
logging:
level:
org.springframework.web.servlet: ERROR
---
#####################################################################
######################## 开发环境profile ##########################
#####################################################################
spring:
profiles: dev
logging:
level:
ROOT: INFO
com:
xncoding: DEBUG
file: E:/logs/app.log

View File

@ -0,0 +1,23 @@
_____ _______ _____ _____
/\ \ /::\ \ /\ \ /\ \
/::\____\ /::::\ \ /::\____\ /::\ \
/:::/ / /::::::\ \ /:::/ / /::::\ \
/:::/ / /::::::::\ \ /:::/ / /::::::\ \
/:::/ / /:::/~~\:::\ \ /:::/ / /:::/\:::\ \
/:::/ / /:::/ \:::\ \ /:::/____/ /:::/__\:::\ \
/:::/ / /:::/ / \:::\ \ |::| | /::::\ \:::\ \
/:::/ / /:::/____/ \:::\____\ |::| | _____ /::::::\ \:::\ \
/:::/ / |:::| | |:::| | |::| | /\ \ /:::/\:::\ \:::\ \
/:::/____/ |:::|____| |:::| | |::| | /::\____\/:::/__\:::\ \:::\____\
\:::\ \ \:::\ \ /:::/ / |::| | /:::/ /\:::\ \:::\ \::/ /
\:::\ \ \:::\ \ /:::/ / |::| | /:::/ / \:::\ \:::\ \/____/
\:::\ \ \:::\ /:::/ / |::|____|/:::/ / \:::\ \:::\ \
\:::\ \ \:::\__/:::/ / |:::::::::::/ / \:::\ \:::\____\
\:::\ \ \::::::::/ / \::::::::::/____/ \:::\ \::/ /
\:::\ \ \::::::/ / ~~~~~~~~~~ \:::\ \/____/
\:::\ \ \::::/ / \:::\ \
\:::\____\ \::/____/ \:::\____\
\::/ / ~~ \::/ /
\/____/ \/____/

View File

@ -0,0 +1,97 @@
package com.xncoding.webservice;
import com.xncoding.webservice.model.User;
import com.xncoding.webservice.service.ICommonService;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApplicationTests {
@LocalServerPort
private Integer port;
/**
* 接口地址
*/
private String wsdlAddress;
@Before
public void prepare() {
wsdlAddress = "http://localhost:" + port + "/services/CommonService?wsdl";
}
/**
* 方式1.代理类工厂的方式,需要拿到对方的接口
*/
@Test
public void cl1() {
try {
// 接口地址
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(wsdlAddress);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(ICommonService.class);
// 创建一个代理接口实现
ICommonService cs = (ICommonService) jaxWsProxyFactoryBean.create();
// 数据准备
String userName = "Leftso";
// 调用代理接口的方法调用并返回结果
String result = cs.sayHello(userName);
System.out.println("返回结果:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 方式2. 动态调用方式
*/
@Test
public void cl2() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(wsdlAddress);
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
Object[] objects;
try {
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("sayHello", "Leftso");
System.out.println("返回类型:" + objects[0].getClass());
System.out.println("返回数据:" + objects[0]);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
/**
* 方式2. 动态调用方式返回对象User
*/
@Test
public void cl3() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(wsdlAddress);
Object[] objects;
try {
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("getUser", "张三");
System.out.println("返回类型:" + objects[0].getClass());
System.out.println("返回数据:" + objects[0]);
User user = (User) objects[0];
System.out.println("返回对象User.name=" + user.getName());
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
}