`
schy_hqh
  • 浏览: 555816 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

JAX与spring的无缝集成---增加Handler和Exception(二)

 
阅读更多

客户端也使用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错误!"异常;

以上两项都通过验证,服务端才继续为客户端提供服务。

 

 

分享到:
评论

相关推荐

    jackson-jaxrs-json-provider-2.7.8-API文档-中文版.zip

    赠送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依赖信息文件:...

    jackson-jaxrs-json-provider-2.7.8-API文档-中英对照版.zip

    赠送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依赖信息文件:...

    fastjson-jaxrs-json-provider-0.3.1-API文档-中文版.zip

    赠送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的例子(含服务端和客户端)

    标题中的“一个包含jax-ws和jax-rs的例子(含服务端和客户端)”是指这是一个示例项目,它演示了如何使用Java API for XML Web Services (JAX-WS)和Java API for RESTful Web Services (JAX-RS)来创建和消费Web服务。...

    jax-rs jax-ws所需包,亲测可用

    JAX-WS提供了处理XML消息、WSDL(Web服务描述语言)和UDDI(统一描述、发现和集成)的标准API。与JAX-RS不同,JAX-WS通常涉及更复杂的配置和更多的协议层,但它的优势在于支持事务、安全性、可靠消息传递等高级特性...

    cxf-rt-frontend-jaxrs-3.0.1-API文档-中文版.zip

    赠送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...

    JAX-RS-FileUpload-Jersey-Example

    通过理解和实践这个“RESTfulExample”,你可以熟练掌握如何在JAX-RS和Jersey环境中处理文件上传,为你的Web服务增加更多功能。这是一项基础但重要的技能,对于构建交互性强、数据传输丰富的应用程序非常有价值。

    spring-boot-cxf-jaxrs:Spring Boot CXF 集成

    CXF 的 Spring Boot 集成,特别是 JAX-RS。 用法 将以下内容添加到您的pom.xml (在适当的情况下更新&lt;version&gt; ): &lt;groupId&gt;com.internetitem.spring&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-cxf-jaxrs ...

    jax-0.3.25-py3-none-any.whl

    文件格式:whl安装步骤:切换到whl路径执行pip install [whl文件名]注意whl对应python版本

    jackson-jaxrs-base-2.7.8-API文档-中英对照版.zip

    赠送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-client-proxy:Spring JAX-RS客户端代理

    Spring JAX-RS客户端代理 一个在Spring中更容易注册基于代理的JAX-RS客户端的工具。 特征 基于类路径扫描的JAX-RS客户端代理的简单设置。 支持 高枕无忧 CXF 球衣 设置 为了开始和运行,只需将工件添加到您的Maven ...

    Spring MVC与JAX-RS比较与分析

    如果你使用Spring进行开发,那可能想知道(或者有人曾问过你)Spring MVC与JAX-RS有何异同点?更进一步,如果你手头有一个Spring MVC应用,使用了控制类继承(SimpleFormController等),你可能还意识不到现在的...

    jackson-jaxrs-base-2.7.8-API文档-中文版.zip

    赠送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服务 rest简单增删改查 集成spring webService

    **JAX-RS CXF Web服务 RESTful CRUD与Spring集成详解** JAX-RS(Java API for RESTful Web Services)是Java平台上的一个标准,用于创建RESTful Web服务。REST是一种轻量级的架构风格,它以资源为中心,通过HTTP...

    jax-ws-spring

    【jax-ws-spring】是将Java API for XML Web Services(JAX-WS)与Spring框架结合使用的技术,主要用于创建和消费Web服务。这个主题涵盖了Web服务的基础,如SOAP(Simple Object Access Protocol)协议和WSDL(Web ...

    spring-framework-3.0.5.RELEASE-dependencies1

    Spring对JAX-WS有良好的集成,使得在Spring应用中使用Web服务变得简单。 5. **org.apache.commons**:Apache Commons项目提供了一系列实用工具类,如Commons Lang、Commons IO等,它们在Spring框架中被广泛使用,...

    JAX-WS-Deploy-To-Tomcat-Example

    JAX-WS(Java API for XML Web Services)是Java平台上的一个标准,用于构建和部署基于SOAP的Web服务。本示例将详细介绍如何使用JAX-WS开发Web服务,并将其部署到Apache Tomcat服务器上。 1. **JAX-WS简介** JAX-...

    swagger-spring-jaxrs-sample-app

    昂首阔步的春天jaxrs示例应用程序使用JAX-RS设置Spring Boot Rest App 在pom.xml中添加spring-boot-starter-jersey&lt; dependencies&gt;&lt; dependency&gt;&lt; groupId&gt;org.springframework.boot&lt;/ groupId&gt;&lt; artifactId&gt;spring-...

    Spring3_JAX-WS

    **Spring3_JAX-WS** 是一个学习...通过这个项目,学习者可以理解Spring与JAX-WS的结合,如何使用注解简化开发,以及如何进行Web服务的测试。对于想要深入理解Web服务和Spring框架的人来说,这是一个实用的学习资源。

    JAX-RS+spring

    1. **集成方式**: 通常通过Spring的Servlet容器如Tomcat或Jetty来部署JAX-RS应用,Spring负责应用的上下文管理和依赖注入,JAX-RS处理REST接口。 2. **Spring REST**: 使用Spring MVC的`@RestController`注解创建...

Global site tag (gtag.js) - Google Analytics