SpringBoot整合CXF,使用webService
1、SpringBoot整合CXF,使用webService
CXF,Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF,继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。Apache CXF已经是一个正式的Apache顶级项目。
1、导包
1.1、确定SpringBoot版本,才能正确导入与之版本契合的CXF包
使用IDEA打开已有的项目,显示如图所示,打开左侧Project面板;在project面板下找到如图所示的External Libraries;
在External Libraries面板下中找到如图所示的Spirng-boot:xx.xx.xxrelease,即是xx.xx.xx的版本。
或者
或者点击界面右侧的Maven Project按钮;打开dependencies后,找到如图所示的spring-boot-start,即可查看到版本。
1.2、正确引入pom.xml文件
<!--webService接口依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.6</version>
</dependency>
2、创建实体类
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = -3628469724795296287L;
private int id;
private String userName;
private String passWord;
private String userSex;
private String nickName;
public int getId() {
return id;
}
public void setId(int 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;
}
public String getUserSex() {
return userSex;
}
public void setUserSex(String userSex) {
this.userSex = userSex;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
}
3、创建Service接口
package com.alibaba.wms.service;
import com.alibaba.wms.model.User;
import javax.jws.WebMethod;
import javax.jws.WebService;
/**
* name 暴露服务名称
* targetNamespace 命名空间,一般是接口的包名反转
*/
@WebService(
name = "UserService",
targetNamespace = "http://service.wms.alibaba.com"
)
public interface UserService {
/**
* @WebMethod 标注该方法为webservice暴露的方法,用于向外公布,它修饰的方法是webservice方法,去掉也没影响的,类似一个注释信息。
* @param userId
* @return
*/
@WebMethod
User getUser(String userId);
@WebMethod
String getUserName( String userId);
}
4、创建接口实现类
package com.alibaba.wms.service.impl;
import com.alibaba.wms.model.User;
import com.alibaba.wms.service.UserService;
import org.springframework.stereotype.Component;
import javax.jws.WebService;
import java.util.HashMap;
import java.util.Map;
/**
* serviceName 与接口中指定的name一致
* targetNamespace 与接口中的命名空间一致,一般是接口的包名反转
* endpointInterface 接口地址
*/
@WebService(serviceName="UserService",//对外发布的服务名
targetNamespace="http://service.wms.alibaba.com",//指定你想要的名称空间,通常使用使用包名反转
endpointInterface="com.alibaba.wms.service.UserService")
@Component
public class UserServiceImpl implements UserService {
private Map<String, User> userMap = new HashMap<String, User>();
public UserServiceImpl() {
System.out.println("向实体类插入数据");
User user = new User();
user.setId(111);
user.setUserName("test1");
userMap.put(user.getId()+"", user);
user = new User();
user.setId(112);
user.setUserName("test2");
userMap.put(user.getId()+"", user);
user = new User();
user.setId(113);
user.setUserName("test3");
userMap.put(user.getId()+"", user);
}
@Override
public String getUserName(String userId) {
return "userId为:" +userMap.get( userId).getUserName();
}
@Override
public User getUser(String userId) {
System.out.println("userMap是:"+userMap);
return userMap.get(userId);
}
}
5、创建CXF类
package com.alibaba.wms.config;
import com.alibaba.wms.service.UserService;
import com.alibaba.wms.service.impl.UserServiceImpl;
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.beans.factory.annotation.Autowired;
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 {
/**
* 此方法作用是改变项目中服务名的前缀名,此处127.0.0.1或者localhost不能访问时,请使用ipconfig查看本机ip来访问
* 此方法被注释后:wsdl访问地址为http://127.0.0.1:8080/services/user?wsdl
* 去掉注释后:wsdl访问地址为:http://127.0.0.1:8080/soap/user?wsdl
* @return
*/
@Bean
public ServletRegistrationBean disServlet() {
return new ServletRegistrationBean(new CXFServlet(),"/soap/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Autowired
UserService userService;
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), userService);
endpoint.publish("/UserService");
return endpoint;
}
/* 非自动注入 UserService 的调用方式
@Bean
public UserService userService() {
return new UserServiceImpl();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), userService());
endpoint.publish("/UserService");
return endpoint;
}*/
}
6、开放访问权限
package com.alibaba.wms.config;
import com.alibaba.commons.constants.PermitAllUrl;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName: ResourceServerConfig
* @Description:TODO 资源服务配置
*/
@EnableResourceServer
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().exceptionHandling()
.authenticationEntryPoint(
(request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and().authorizeRequests()
//非常重要,必须 放开权限的url,否则只有登录之后才可以访问
.antMatchers(PermitAllUrl.permitAllUrl("/soap/**")).permitAll()
.anyRequest().authenticated().and().httpBasic();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
7、页面访问
8、编写测试类
Client的pom文件引入
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
package com.huaxun.springboot;
import com.huaxun.springboot.service.UserService;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.http.HttpEntity;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
Test.main1();
Test.main2();
}
/**
* 1.代理类工厂的方式,需要拿到对方的接口地址
*/
public static void main1() {
try {
// 接口地址
String address = "http://127.0.0.1:8080/soap/user?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(UserService.class);
// 创建一个代理接口实现
UserService us = (UserService) jaxWsProxyFactoryBean.create();
// 数据准备
String userId = "111";
// 调用代理接口的方法调用并返回结果
String result = us.getUserName(userId);
System.out.println("返回结果:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 2:httpClient调用
*/
public static void main2() {
try {
final String SERVER_URL = "http://127.0.0.1:8080/soap/user"; // 定义需要获取的内容来源地址
HttpPost request = new HttpPost(SERVER_URL);
String soapRequestData = getRequestXml();
HttpEntity re = new StringEntity(soapRequestData, HTTP.UTF_8);
request.setHeader("Content-Type","application/soap+xml; charset=utf-8");
request.setEntity(re);
HttpResponse httpResponse = new DefaultHttpClient().execute(request);
if (httpResponse.getStatusLine().getStatusCode() ==200) {
String xmlString = EntityUtils.toString(httpResponse.getEntity());
String jsonString = parseXMLSTRING(xmlString);
System.out.println("---"+jsonString);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static String parseXMLSTRING(String xmlString) {
String returnJson = "";
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
Element root = doc.getDocumentElement();//根节点
Node node = root.getFirstChild();
while (!node.getNodeName().equals("String")) {
node = node.getFirstChild();
}
if (node.getFirstChild() != null) returnJson = node.getFirstChild().getNodeValue();
System.out.println("获取的返回参数为:" + returnJson);
} catch (Exception e) {
e.printStackTrace();
}
return returnJson;
}
private static String getRequestXml(){
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\"?>");
sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
sb.append(" xmlns:sam=\"http://service.springboot.huaxun.com/\" "); //前缀,这一串由服务端提供
sb.append(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");
sb.append(" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
sb.append("<soap:Header/>");
sb.append("<soap:Body>");
sb.append("<sam:getUserName>"); //“getUserName”调用方法名
sb.append("<userId>111</userId>"); //传参,“userId”是配置在服务端的参数名称,“111”是要传入的参数值
sb.append("</sam:getUserName>");
sb.append("</soap:Body>");
sb.append("</soap:Envelope>");
return sb.toString();
}
}
9、参考链接:
本文作者:Journey&Flower
本文链接:https://www.cnblogs.com/JourneyOfFlower/p/15950338.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步