springBoot整合CXF并实现用户名密码校验的方法

网友投稿 234 2023-01-23


springBoot整合CXF并实现用户名密码校验的方法

准备工作:

创建springBoot项目webservice_server

创建springBoot项目webservice_client

分别添加CXF的依赖:

org.apache.cxf

cxf-spring-boot-starter-jaxws

3.1.11

一.定义要发布的接口和实现类

接口:

@WebService

public interface AppService {

@WebMethod

String getUserName(@WebParam(name = "id") String id) throws UnsupportedEncodingException;

@WebMethod

public User getUser(String id) throws UnsupportedEncodingException;

}

实现类:

//name暴露的服务名称, targetNamespace:命名空间,设置为接口的包名倒写(默认是本类包名倒写). endpointInterface接口地址

@WebService(name = "test" ,targetNamespace ="http://cxf.wolfcode.cn/" ,endpointInterface = "cn.wolfcode.cxf.AppService")

public class AppServiceImpl implements AppService {

jsONResult jsonResult = JSONResult.getJsonResult();

@Override

public String getUserName(String id) throws UnsupportedEncodingException {

System.out.println("==========================="+id);

JSONResult result= JSONResult.getJsonResult();

result.setSuccess(true);

result.setMessage("明哥");

return result.toJsonObject();

}

@Override

public User getUser(String id)throws UnsupportedEncodiENfUzngException {

System.out.println("==========================="+id);

return new User(1L,"明哥");

}

}

二.发布服务

1.定义配置类

@Configuration

public class CxfConfig {

//默认servlet路径/*,如果覆写则按照自己定义的来

@Bean

public ServletRegistrationBean dispatcherServlet() {

return new ServletRegistrationBean(new CXFServlet(), "/services/*");

}

@Bean(name = Bus.DEFAULT_BUS_ID)

public SpringBus springBus() {

return new SpringBus();

}

//把实现类交给spring管理

@Bean

public AppService appService() {

return new AppServiceImpl();

}

//终端路径

@Bean

public Endpoint endpoint() {

EndpointImpl endpoint = new EndpointImpl(springBus(), appService());

endpoint.getInInterceptors().add(new AuthInterceptor());//添加校验拦截器

endpoint.publish("/user");

return endpoint;

}

}

2.发布服务

@SpringBootApplication

public class WebserviceApplication {

public static void main(String[] args) {

SpringApplication.run(WebserviceApplication.class, args);

}

}

因为我添加了用户名和密码校验所以在发布之前还需要定义自己校验用户名和密码的Interceptor

public class AuthInterceptor extends AbstractPhaseInterceptor {

Logger logger = LoggerFactory.getLogger(this.getClass());

private static final String USERNAME="root";

private static final String PASSWORD="admin";

public AuthInterceptor() {

//定义在哪个阶段进行拦截

super(Phase.PRE_PROTOCOL);

}

@Override

public void handleMessage(SoapMessage soapMessage) throws Fault {

List

headers = null;

String username=null;

String password=null;

try {

headers = soapMessage.getHeaders();

} catch (Exception e) {

logger.error("getSOAPHeader error: {}",e.getMessage(),e);

}

if (headers == null) {

throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));

}

//获取用户名,密码

for (Header header : headers) {

SoapHeader soapHeader = (SoapHeader) header;

Element e = (Element) soapHeader.getObject();

NodeList usernameNode = e.getElementsByTagName("username");

NodeList pwdNode = e.getElementsByTagName("password");

username=usernameNode.item(0).getTextContent();

password=pwdNode.item(0).getTextContent();

if( StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){

throw new Fault(new IllegalArgumentException("用户信息为空"));

}

}

//校验用户名密码

if(!(username.equals(USERNAME) && password.equals(PASSWORD))){

SOAPException soapExc = new SOAPException("认证失败");

logger.debug("用户认证信息错误");

throw new Fault(soapExc);

}

}

}

现在可以发布服务了.....

发布完成后访问http://localhost:8888/services/user?wsdl

能够出现以下界面就是发布OK

三.调用服务

1.新建调用端项目,添加依赖

2.因为示例演示了两种调用方式,其中一种需要用到接口,所以先把服务接口拷贝一份到调用端项目中(代码就是上面接口的代码)

3.因为服务端添加了用户名密码校验,所以调用的时候需要添加用户名密码信息, 所以需要使用下面的Interceptor完成添加用户名密码信息

/**

* Created by sky on 2018/2/27.

*/

public class LoginInterceptor extends AbstractPhaseInterceptor {

private String username="root";

private String password="admin";

public LoginInterceptor(String username, String password) {

//设置在发送请求前阶段进行拦截

super(Phase.PREPARE_SEND);

this.username=username;

this.password=password;

}

@Override

public void handleMessage(SoapMessage soapMessage) throws Fault {

List

headers = soapMessage.getHeaders();

Document doc = DOMUtils.createDocument();

Element auth = doc.createElementNS("http://cxf.wolfcode.cn/","SecurityHeader");

Element UserName = doc.createElement("username");

Element UserPass = doc.createElement("password");

UserName.setTextContent(username);

UserPass.setTextContent(password);

auth.appendChild(UserName);

auth.appendChild(UserPass);

headers.add(0, new Header(new QName("SecurityHeader"),auth));

}

}

4.调用接口

/**

* Created by sky on 2018/2/27.

*/

public class Cxfclient {

//webservice接口地址

private static String address = "http://localhost:8888/services/user?wsdl";

//测试

public static void main(String[] args) {

test1();

test2();

}

/**

* 方式1:使用代理类工厂,需要拿到对方的接口

*/

public static void test1() {

try {

// 代理工厂

JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();

// 设置代理地址

jaxWsProxyFactoryBean.setAddress(address);

//添加用户名密码拦截器

jaxWsProxyFactoryBean.getOutInterceptors().add(new LoginInterceptor("root","admin"));;

// 设置接口类型

jaxWsProxyFactoryBean.setServiceClass(AppService.class);

// 创建一个代理接口实现

AppService cs = (AppService) jaxWsProxyFactoryBean.create();

// 数据准备

String LineId = "1";

// 调用代理接口的方法调用并返回结果

User result = (User)cs.getUser(LineId);

System.out.println("==============返回结果:" + result);

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 动态调用方式

*/

public static void test2() {

// 创建动态客户端

JaxWsDynamicClientFactoENfUzry dcf = JaxWsDynamicClientFactory.newInstance();

Client client = dcf.createClient(address);

// 需要密码的情况需要加上用户名和密码

client.getOutInterceptors().add(new LoginInterceptor("root","admin"));

Object[] objects = new Object[0];

try {

// invoke("方法名",参数1,参数2,参数3....);

System.out.println("======client"+client);

objects = client.invoke("getUserName", "1");

System.out.println("返回数据:" + objects[0]);

} catch (Exception e) {

e.printStackTrace();

}

}

}

嗯...总体上就是这么简单, 演示代码可以去这里下载:http://xz.jb51.net:81/201808/yuanma/springBoot_WebService_jb51.rar


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java 读写锁实现原理浅析
下一篇:自动连接共享文件夹(共享文件夹自动同步)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~