客户端也使用spring集成JAX-WS。但是有一个问题需要处理!
想在SOAP消息中加入HEADER该怎样加入呢,使用Handler!
之前使用handler都是通过在实现类上使用注解@HandlerChain(file="handler-chain.xml")进行标注引入的
//声明handler的位置 @HandlerChain(file="handler-chain.xml") public class StudentWSService extends Service { ... }
然后手动创建这个实现类的对象,这样自然能讲handler加入到程序运行逻辑中。
IStudentWSService iservice = new StudentWSService().getStudentServicePort();
但是,将JAX-WS与spring集成后,使用的实现类是由spring提供的一个代理来完成,这将如何做呢???
通过JaxWsPortProxyFactoryBean的最上层父类LocalJaxWsServiceFactory中的属性handlerResolver来定义!
编写Handler
package com.hqh.student.ws.handler; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPConstants; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; public class LicenseHandler implements SOAPHandler<SOAPMessageContext> { public void close(MessageContext ctx) { } public boolean handleFault(SOAPMessageContext ctx) { return false; } public boolean handleMessage(SOAPMessageContext context) { try { Boolean out = (Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY); if(out) { System.out.println("message outing..."); SOAPEnvelope soapEnv = context.getMessage().getSOAPPart().getEnvelope(); SOAPBody soapBody = soapEnv.getBody(); //获取当前在调用服务的哪个方法 String localName = soapBody.getFirstChild().getLocalName(); // System.out.println(localName); if(!"getStudent".equals(localName)) { return true; } //如果是getStudent,则加入头信息 SOAPHeader soapHeader = soapEnv.getHeader(); if(soapHeader==null) { soapHeader = soapEnv.addHeader(); } //创建QName String nameSpace = "http://ws.student.hqh.com";//wsdl的targetNamespace String part = "license";//message的name,必须与wsdl中定义的一致 String prefix = "ns";//前缀 QName headerQName = new QName(nameSpace, part, prefix); //将QName加入Header,并设定值 soapHeader.addHeaderElement(headerQName).setValue("admin"); } else { System.out.println("message come back..."); } return true; } catch (SOAPException e) { e.printStackTrace(); } return false; } public Set<QName> getHeaders() { return null; } }
编写HandlerResolver
package com.hqh.student.ws.handler; import java.util.ArrayList; import java.util.List; import javax.xml.ws.handler.Handler; import javax.xml.ws.handler.HandlerResolver; import javax.xml.ws.handler.PortInfo; import org.springframework.stereotype.Service; import com.sun.xml.ws.util.JAXWSUtils; /** * 将新的HandlerList返回,由spring提供的代理服务进行调用 * 这样就达到了使用Handler的目的 * 怎样通过paramPortInfo获取到已有的Handler呢??? */ @Service("soapHeaderHandler") public class SOAPHeaderHandler implements HandlerResolver { private List<Handler> newHandlerList = null; public SOAPHeaderHandler() { newHandlerList = new ArrayList<Handler>(); newHandlerList.add(new LicenseHandler()); } public List<Handler> getHandlerChain(PortInfo paramPortInfo) { return newHandlerList; } }
让spring注入handler到其代理服务中
在spring为JAX-WS提供的代理bean中配置Handler(关键),这样就能将Handler注入到代理对象中了!
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core/spring-jax-ws-core.xsd http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet/spring-jax-ws-servlet.xsd"> <context:annotation-config/> <context:component-scan base-package="com.hqh.client"/> <!-- 声明需要被spring进行注解扫描 --> <context:component-scan base-package="com.hqh.student.ws.handler"/> <!-- 利用spring完成webservice服务的注入! --> <!-- Accessing web services using JAX-WS --> <bean id="wsService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"> <property name="serviceInterface" value="com.hqh.student.ws.IStudentWSService"/> <property name="wsdlDocumentUrl" value="http://localhost:9999/server/jaxws-spring?wsdl"/> <property name="namespaceUri" value="http://ws.student.hqh.com"/> <property name="serviceName" value="StudentWSService"/> <property name="portName" value="studentServicePort"/> <!-- 将处理头信息的Handler注入到JaxWsPortProxyFactoryBean中--> <property name="handlerResolver" ref="soapHeaderHandler"></property> </bean> <!-- 依赖注入 --> <bean id="client" class="com.hqh.client.ws.controller.ClientController"> <property name="studentWsService" ref="wsService"></property> </bean> </beans>
服务端增加异常类,如果调用服务端的getStudent()没有头信息或者头信息中的license错误,则抛出异常
package com.hqh.student.exception; /** * 处理webservice的异常最好继承Exception,而不是RuntimeException * 该Exception就是wsdl中新增的自定义Exception * @author lenovo * */ public class StudentWsException extends Exception { public StudentWsException() { super(); } public StudentWsException(String message, Throwable cause) { super(message, cause); } public StudentWsException(String message) { super(message); } public StudentWsException(Throwable cause) { super(cause); } }
在wsdl中增加异常消息
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws.student.hqh.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="StudentWSService" targetNamespace="http://ws.student.hqh.com"> <!-- 指定schema --> <wsdl:types> <xsd:schema targetNamespace="http://ws.student.hqh.com"> <xsd:include schemaLocation="student.xsd"/> <!-- 增加头信息(for HEADER) --> <xsd:element name="license" type="xsd:string"/> <!-- 增加异常 --> <xsd:element name="StudentWsException" type="tns:StudentWsException"></xsd:element> <xsd:complexType name="StudentWsException"> <xsd:sequence> <xsd:element name="errorMsg" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema> </wsdl:types> <!-- 增加异常消息 --> <wsdl:message name="StudentWsException"> <wsdl:part name="fault" element="tns:StudentWsException"/> </wsdl:message> <!-- 为license创建新的message(for HEADER) --> <wsdl:message name="license"> <wsdl:part name="license" element="tns:license"></wsdl:part> </wsdl:message> <!-- 指定方法 --> <wsdl:message name="getStudent"> <wsdl:part element="tns:getStudent" name="parameters" /> </wsdl:message> <wsdl:message name="getStudentResponse"> <wsdl:part element="tns:getStudentResponse" name="parameters" /> </wsdl:message> <wsdl:message name="list"> <wsdl:part element="tns:list" name="parameters" /> </wsdl:message> <wsdl:message name="listResponse"> <wsdl:part element="tns:listResponse" name="parameters" /> </wsdl:message> <wsdl:message name="listReward"> <wsdl:part element="tns:listReward" name="parameters" /> </wsdl:message> <wsdl:message name="listRewardResponse"> <wsdl:part element="tns:listRewardResponse" name="parameters" /> </wsdl:message> <!-- 指定接口 --> <wsdl:portType name="IStudentWSService"> <wsdl:operation name="getStudent"> <wsdl:input message="tns:getStudent" /> <wsdl:output message="tns:getStudentResponse" /> <!-- 异常 --> <wsdl:fault name="StudentWsException" message="tns:StudentWsException"></wsdl:fault> </wsdl:operation> <wsdl:operation name="list"> <wsdl:input message="tns:list" /> <wsdl:output message="tns:listResponse" /> </wsdl:operation> <wsdl:operation name="listReward"> <wsdl:input message="tns:listReward" /> <wsdl:output message="tns:listRewardResponse" /> </wsdl:operation> </wsdl:portType> <!-- 指定接口中的方法的参数编码格式 --> <wsdl:binding name="studentSOAP" type="tns:IStudentWSService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="getStudent"> <wsdl:input> <!-- add方法的header中加入license消息 (for HEADER) --> <soap:header use="literal" part="license" message="tns:license"/> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> <!-- 异常 --> <wsdl:fault name="StudentWsException"> <soap:fault name="StudentWsException" use="literal"/> </wsdl:fault> </wsdl:operation> <wsdl:operation name="list"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="listReward"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <!-- 指定服务名称、端口、地址 --> <wsdl:service name="StudentWSService"> <wsdl:port binding="tns:studentSOAP" name="studentServicePort"> <soap:address location="http://localhost:8080/student-web/ws/" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
服务端的接口和实现类抛出异常
@WebService(name = "IStudentWSService", targetNamespace = "http://ws.student.hqh.com") public interface IStudentWSService { /** * * @param number * @return * returns com.hqh.student.ws.Student */ @WebMethod @WebResult(name = "stu", targetNamespace = "") @RequestWrapper(localName = "getStudent", targetNamespace = "http://ws.student.hqh.com") @ResponseWrapper(localName = "getStudentResponse", targetNamespace = "http://ws.student.hqh.com") public Student getStudent( @WebParam(name = "number", targetNamespace = "") String number, @WebParam(name="license", header=true) String license) throws StudentWsException;
@WebService(endpointInterface="com.hqh.student.ws.IStudentWSService", serviceName="StudentWSService", portName="studentServicePort", targetNamespace="http://ws.student.hqh.com", wsdlLocation="/WEB-INF/wsdl/student.wsdl") //该对象交由spring管理,studentWsService即为该实现类在bean容器中的name @Component("studentWsService") public class StudentWSServiceImpl implements IStudentWSService{ // private static final BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml"); // public StudentWSServiceImpl() { // if(studentService==null) { // studentService = factory.getBean(StudentService.class); // } // } //自动注入 @Resource private StudentService studentService; @Override public Student getStudent(String number, String license) throws StudentWsException { // studentService = (StudentService) WebUtil.getBean(StudentService.class); // studentService = (StudentService) BeanFactoryUtil.getBean(StudentService.class); //根据license进行处理 System.out.println("client send license:"+license); if(license==null || "".equals(license)) throw new StudentWsException("SOAP消息HEADER不能为空!"); if(!license.equals("admin")) throw new StudentWsException("SOAP消息HEADER携带的license错误!"); return studentService.getStudent(number); }
从新生成客户端的java文件,调用服务时捕获异常消息
package com.hqh.client.ws.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.hqh.student.ws.IStudentWSService; import com.hqh.student.ws.Student; import com.hqh.student.ws.StudentWsException_Exception; @Controller public class ClientController { /** * 容器初始化第一次,会调用setters进行注入,但是第2次开始,ClientController变为一个新的对象 * 导致studentWsService为NULL,所以,这里使用static来保存第一次初始化好webservice接口的代理对象 * 这里是使用配置文件的方式利用spring提供的配置示例进行注入的 * 用注解注入又该怎样做呢? */ private static IStudentWSService studentWsService; //通过setters方法进行注入! public void setStudentWsService(IStudentWSService wsService) { studentWsService = wsService; } @RequestMapping(value="/getStudent",method=RequestMethod.GET) public String getStudent() { return "index"; } @RequestMapping(value="/getStudent",method=RequestMethod.POST) public String getStudent(String number,Model model) { Student stu = null; try { stu = studentWsService.getStudent(number); } catch (StudentWsException_Exception e) { //调用服务如果发生异常,将异常显示到页面中 model.addAttribute("error", e.getMessage()); return "index"; } if(stu==null) { model.addAttribute("error", "不存在!"); } else { model.addAttribute(stu); } return "index"; } }
客户端调用getStudent()
如果没有传递Header,抛出“SOAP消息HEADER不能为空!”异常;
如果传递了Header,但license不是"admin",抛出"SOAP消息HEADER携带的license错误!"异常;
以上两项都通过验证,服务端才继续为客户端提供服务。
相关推荐
赠送jar包:jackson-jaxrs-json-provider-2.7.8.jar; 赠送原API文档:jackson-jaxrs-json-provider-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-json-provider-2.7.8-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:jackson-jaxrs-json-provider-2.7.8.jar; 赠送原API文档:jackson-jaxrs-json-provider-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-json-provider-2.7.8-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:fastjson-jaxrs-json-provider-0.3.1.jar; 赠送原API文档:fastjson-jaxrs-json-provider-0.3.1-javadoc.jar; 赠送源代码:fastjson-jaxrs-json-provider-0.3.1-sources.jar; 赠送Maven依赖信息文件:...
标题中的“一个包含jax-ws和jax-rs的例子(含服务端和客户端)”是指这是一个示例项目,它演示了如何使用Java API for XML Web Services (JAX-WS)和Java API for RESTful Web Services (JAX-RS)来创建和消费Web服务。...
JAX-WS提供了处理XML消息、WSDL(Web服务描述语言)和UDDI(统一描述、发现和集成)的标准API。与JAX-RS不同,JAX-WS通常涉及更复杂的配置和更多的协议层,但它的优势在于支持事务、安全性、可靠消息传递等高级特性...
赠送jar包:cxf-rt-frontend-jaxrs-3.0.1.jar; 赠送原API文档:cxf-rt-frontend-jaxrs-3.0.1-javadoc.jar; 赠送源代码:cxf-rt-frontend-jaxrs-3.0.1-sources.jar; 赠送Maven依赖信息文件:cxf-rt-frontend-jaxrs...
通过理解和实践这个“RESTfulExample”,你可以熟练掌握如何在JAX-RS和Jersey环境中处理文件上传,为你的Web服务增加更多功能。这是一项基础但重要的技能,对于构建交互性强、数据传输丰富的应用程序非常有价值。
CXF 的 Spring Boot 集成,特别是 JAX-RS。 用法 将以下内容添加到您的pom.xml (在适当的情况下更新<version> ): <groupId>com.internetitem.spring</groupId> <artifactId>spring-boot-cxf-jaxrs ...
文件格式:whl安装步骤:切换到whl路径执行pip install [whl文件名]注意whl对应python版本
赠送jar包:jackson-jaxrs-base-2.7.8.jar; 赠送原API文档:jackson-jaxrs-base-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-base-2.7.8-sources.jar; 赠送Maven依赖信息文件:jackson-jaxrs-base-2.7.8.pom;...
Spring JAX-RS客户端代理 一个在Spring中更容易注册基于代理的JAX-RS客户端的工具。 特征 基于类路径扫描的JAX-RS客户端代理的简单设置。 支持 高枕无忧 CXF 球衣 设置 为了开始和运行,只需将工件添加到您的Maven ...
如果你使用Spring进行开发,那可能想知道(或者有人曾问过你)Spring MVC与JAX-RS有何异同点?更进一步,如果你手头有一个Spring MVC应用,使用了控制类继承(SimpleFormController等),你可能还意识不到现在的...
赠送jar包:jackson-jaxrs-base-2.7.8.jar; 赠送原API文档:jackson-jaxrs-base-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-base-2.7.8-sources.jar; 赠送Maven依赖信息文件:jackson-jaxrs-base-2.7.8.pom;...
**JAX-RS CXF Web服务 RESTful CRUD与Spring集成详解** JAX-RS(Java API for RESTful Web Services)是Java平台上的一个标准,用于创建RESTful Web服务。REST是一种轻量级的架构风格,它以资源为中心,通过HTTP...
【jax-ws-spring】是将Java API for XML Web Services(JAX-WS)与Spring框架结合使用的技术,主要用于创建和消费Web服务。这个主题涵盖了Web服务的基础,如SOAP(Simple Object Access Protocol)协议和WSDL(Web ...
Spring对JAX-WS有良好的集成,使得在Spring应用中使用Web服务变得简单。 5. **org.apache.commons**:Apache Commons项目提供了一系列实用工具类,如Commons Lang、Commons IO等,它们在Spring框架中被广泛使用,...
JAX-WS(Java API for XML Web Services)是Java平台上的一个标准,用于构建和部署基于SOAP的Web服务。本示例将详细介绍如何使用JAX-WS开发Web服务,并将其部署到Apache Tomcat服务器上。 1. **JAX-WS简介** JAX-...
昂首阔步的春天jaxrs示例应用程序使用JAX-RS设置Spring Boot Rest App 在pom.xml中添加spring-boot-starter-jersey< dependencies>< dependency>< groupId>org.springframework.boot</ groupId>< artifactId>spring-...
**Spring3_JAX-WS** 是一个学习...通过这个项目,学习者可以理解Spring与JAX-WS的结合,如何使用注解简化开发,以及如何进行Web服务的测试。对于想要深入理解Web服务和Spring框架的人来说,这是一个实用的学习资源。
1. **集成方式**: 通常通过Spring的Servlet容器如Tomcat或Jetty来部署JAX-RS应用,Spring负责应用的上下文管理和依赖注入,JAX-RS处理REST接口。 2. **Spring REST**: 使用Spring MVC的`@RestController`注解创建...