今天就跟大家聊聊有关怎么在springBoot中利用CXF实现用户名密码校验,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
目前成都创新互联已为近1000家的企业提供了网站建设、域名、网站空间、绵阳服务器托管、企业网站设计、竞秀网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
准备工作:
创建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 UnsupportedEncodingException { 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() { // 创建动态客户端 JaxWsDynamicClientFactory 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(); } } }
springboot一种全新的编程规范,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,SpringBoot也是一个服务于框架的框架,服务范围是简化配置文件。
看完上述内容,你们对怎么在springBoot中利用CXF实现用户名密码校验有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。