`

在WebService中使用动态代理模式和Annotation注解

    博客分类:
  • Java
阅读更多

公司接口程序,使用的是直接读取XMl, 然后使用XStream解析返回的 XML 返回生成的对象。 

 

设计中使用了动态代理的模式,

 

并且结合自定义注解来定义常量和传递的参数 。

 

动态代理 :

 

定义了接口 Feed 及相应的方法, 使用注解传递参数和常量 。

 

 

@DefaultParams(@DefaultParam(key="apikey",value=Feed.APIKEY))

@ServiceURL("https://xml.xxxxxx.com/datafeed/Feed.asmx")

public interface Feed {

	/** 提供服务标识 */

	public static final String APIKEY = "82DD63FF-A7EB-47XXXXXXXXXXXXXX";

	/** 获取地区 */

	@GetMethod
	@HotelCache(timeoutByHour=24*7)
	@MethodName("GetFeed")
	@DefaultParams(@DefaultParam(key="feed_id",value="1"))
	@XStreamRoot("/Region_feed/regions")
	@XStreamAnnotation(@XStreamAlias(key="region",value=RegionFeed.class))
	public List<RegionFeed>  getRegionFeed();

}
	
 

在 Action 初始化的时候, 加载 Feed 接口的动态代理:

 

public class HotelListAction extends BaseAction {

	static {

		defaultParams = new ArrayList<Object>();
		FeedDefaultParam param = new FeedDefaultParam();
		param.setOlanguage_id(LEAGUAGE_CODE);
		defaultParams.add(param);
		feed = IXRProxyFactory.newProxyInstance(Feed.class,defaultParams);
	}

	public void geoCity() {
		CityFeedParams params = new CityFeedParams();
		params.setMcountry_id(id);
		List<CityFeed> cities = null;
		try{
			cities = feed.getCityFeed(params);
		}catch(Exception ex){
			logger.error("查找城市不存在!");
		}	

		outputPlainText(JSONArray.fromObject(cities).toString());
	}

}
 

这里使用了自定义的代理工厂,

 

/**
 * 代理工厂
 * @version 1.0 2010-12-4
 * @author ixr_(mail@ixr.name)
 */
public class IXRProxyFactory{
    /** 获取代理对象 */
    public static <T> T newProxyInstance(Class<T> interfaceClass,List<Object> defaultParams){
        IXRProxy proxy = new IXRProxy();
        proxy.setDefaultParams(defaultParams);
        proxy.setInterfaceClass(interfaceClass);
        Object proxyImpl = Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass}, proxy);
        return interfaceClass.cast(proxyImpl);
    }
}
 

其中 ,IXRProxy 就是代理处理逻辑类 ,其继承接口 InvocationHandler  ,实现方法:

public Object invoke(Object proxy, Method method, Object[] args)

此方法体, 会代替被代理接口的每个方法执行,并且返回  Object 对象。

 

public class IXRProxy implements InvocationHandler{

    /** 默认编码 */
    private static final String ENCODING = "utf-8";
    /** 接口 */
    private Class<?> interfaceClass = null;
    
    public void setInterfaceClass(Class<?> interfaceClass){
    	this.interfaceClass = interfaceClass;
    }
    
    /** 默认参数 */
    private List<Object> defaultParams = new ArrayList<Object>();
    public void setDefaultParams(List<Object> defaultParams){
        this.defaultParams = defaultParams;
    }
    
    private Object invoke(Object proxy, HttpClientParam httpClientParam, Method method, Object[] args) throws Throwable {
String xml = null;
        try {
            if(httpClientParam.isGet){
            	xml = HttpClientUtils.getHTML(httpClientParam.url, httpClientParam.params);
            }else{
            	xml = HttpClientUtils.postHTML(httpClientParam.url, httpClientParam.params);
            }
                XStreamAnnotation xStreamAnnotation = method.getAnnotation(XStreamAnnotation.class);
                if (xStreamAnnotation != null) {
                    XStreamAlias[] xStreamAliasArray = xStreamAnnotation.value();
                    for (XStreamAlias xStreamAlias : xStreamAliasArray) {
                        xStream.alias(xStreamAlias.key(), xStreamAlias.value());
                        String[] useAttributes = xStreamAlias.useAttributes();
                        for (String useAttribute : useAttributes) {
                        	xStream.useAttributeFor(xStreamAlias.value(), useAttribute);
                        }
                    }
                   
                }
                Document dom = DocumentHelper.parseText(xml);
                
                return xStream.fromXML(xml);
            } else {
                return null;
            }
        } catch (Exception e) {
        	log.error("取接口数据时出错", e);
        	
        	return null;
        }
    }
 

 

代理方法中, 根据接口定义的注解参数, 转换返回的 XML 所对应的类型, 并且返回。

 

自定义注解 :

 

自定义的注解接口 :

 

public interface IXRProxyAnnotation {
    /** 服务地址 */
    @Documented
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ServiceURL{
        String value(); 
    }
    /** XStream解析类型 */
    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface XStreamAnnotation{
        XStreamAlias[] value();
        AttributeValueConveter[] attributeValueConveters() default {};
    }
    /** XStream解析根目录 */
    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface XStreamRoot{
        String value();
    }
    /** XStream解析类型映射 */
    @Documented
    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface XStreamAlias{
        String key();
        Class<?> value();
        String[] useAttributes() default {};
    }


}
 

注解中, 可定义

        String key();
        Class<?> value();
        String[] useAttributes() default {};

等等参数, 标注注解的时候, 需要提供这些默认值 。。

 

@XStreamAlias(key="country",value=CountryFeed.class)
 

在 invoke 方法中, 通过接口类对象的方法:

//获取接口参数
        String serviceURL = interfaceClass.getAnnotation(ServiceURL.class).value();

 

通过参数: Method method 得到方法标记的参数

//方法标记参数
        DefaultParams defaultParamsAnnotation = method.getAnnotation(DefaultParams.class);
        if(defaultParamsAnnotation != null){
            for (DefaultParam defaultParam : defaultParamsAnnotation.value()) {
                params.put(defaultParam.key(), defaultParam.value());
            }
        }

 

获得传入的参数:

 

        //获取传入参数
        for (Object param : (args == null ? new Object[0] : args)) {
            argsList.add(param);
        }
        //转换请求参数列表
        for (Object param : argsList) {
            Field[] fiedl = param.getClass().getDeclaredFields();
            for (Field field : fiedl) {
                Param paramAnnotation = field.getAnnotation(Param.class);
                if (paramAnnotation != null) {
                    field.setAccessible(true);
                    params.put(paramAnnotation.value().isEmpty() ? field.getName() : paramAnnotation.value(), String.valueOf(field.get(param)));
                }
            }
        }
 

比如,在获取城市数据的时候, 传入参数定义的类 :

 

public class CityFeedParams {
	@Param private Integer mcountry_id; //--国家ID

	public Integer getMcountry_id() {
		return mcountry_id;
	}

	public void setMcountry_id(Integer mcountry_id) {
		this.mcountry_id = mcountry_id;
	}

}

 

必须要在变量前面加自定义注解: @Param

 

才能在invoke方法中,使用 Param paramAnnotation = field.getAnnotation(Param.class); 得到值,传出到Webservice...

 

 

 

分享到:
评论
2 楼 Jxdwuao 2011-05-26  
我晕, 你是 .. 王雪? 
1 楼 IXR 2011-05-26  
  允许我转载下吗?

相关推荐

    2、webservice--常用注解1

    为了简化WebService 的开发过程,Java 提供了一些注解(Annotation),这些注解可以帮助开发者快速地创建和配置 WebService。这篇文章将详细介绍其中的一些常用注解。 @WebService @WebService 是一个基本的...

    Spring + CXF + 注解方式(webService)

    在CXF中,我们可以使用JAX-WS注解如`@WebService`,`@SOAPBinding`,`@WebMethod`等来声明服务接口和方法。这些注解使得代码更加简洁,减少了XML配置文件的需求。例如: ```java @WebService(targetNamespace = ...

    安卓网站交互JSONxmlWebserviceUPnP相关-JsonAnnotation利用注解自动生成Gson‘sModel的库.rar

    在Android开发中,数据交换和网络通信是至关重要的部分,其中JSON、XML、WebService和UPnP等技术扮演着核心角色。本压缩包“安卓网站交互JSONxmlWebserviceUPnP相关-JsonAnnotation利用注解自动生成Gson’s Model的...

    springboot+webservice搭建webservice服务端及使用java客户端两种方式进行调用webservice接口

    在IT行业中,Web Service是一种基于XML的通信标准,允许不同系统之间进行互操作性交互。Spring Boot是一个流行的Java框架,用于简化Spring应用的创建和管理。本教程将讲解如何使用Spring Boot集成Apache CXF(一个...

    2020-WebService帮助文档Idea.docx

    我们使用`@WebService`和`@WebMethod`注解来定义服务端的接口和实现类。然后,我们使用`EndpointImpl`类来发布这个WebService。最后,我们使用客户端来调用服务端的WebService。 WebService的应用 WebService有很...

    web服务开发 使用jdk6注解 注解分析

    在Java开发中,注解(Annotation)是一种强大的元数据机制,它允许程序员在代码中嵌入信息,这些信息可以被编译器、JVM或特定工具在编译时或运行时读取。在 JDK 1.6 版本中,注解的引入极大地简化了 Web 服务的开发...

    Spring + Xfire + 注解方式

    在"Demo_Spring_Xfire_Annotation"这个压缩包文件中,很可能包含了示例代码,用于演示如何在Spring和Xfire环境中使用注解来创建、配置和调用Web服务。可能包括以下几个部分: 1. **服务接口**:定义了服务的公共...

    Spring+CXF 全注解版

    总的来说,"Spring+CXF 全注解版"是关于如何使用注解在Spring和CXF环境中开发和部署Web服务的实践指南,这使得开发更加简洁和高效。通过注解,开发者可以避免大量的XML配置,提高开发效率,同时保持代码的清晰和...

    CXF2.7+Spring3 Java WebService 集成用例

    在这个集成案例中,我们利用Spring 3的注解来声明服务的实现类和Bean定义,例如`@WebService`,`@Component`,`@Autowired`等,这些注解减少了XML配置的需求。 5. **创建Java WebService**: 使用CXF的`@...

    CXF开发webservice服务端

    需要注意的是,`@XmlType`注解中的`propOrder`属性必须与类中的属性顺序保持一致,否则在服务器启动时会出现错误提示。 ##### 3. 接口定义 定义一个名为`HelloWorld`的接口,该接口将包含两个方法:`stringInt` 和 ...

    几种访问和发布webservice服务的示例

    JDK提供了JAX-WS(Java API for XML Web Services)工具集,允许开发者使用注解(Annotation)在Java类中定义服务接口和服务实现。例如,一个简单的服务接口可能如下: ```java @WebService public interface Hello...

    jaxws java webservice需要的jar包

    5. **javax.annotation-api.jar**:包含了Java注解API,如`@WebService`, `@WebMethod`, `@WebResult`等,这些都是JAX-WS中定义Web服务和方法的重要注解。 6. **metro-config.jar** 和 **metro-utils.jar**:这部分...

    springboot工程自定义response注解、自定义规范化返回数据结构

    在Spring Boot应用开发中,构建一个统一的、规范化的返回数据结构对于提升API的使用体验至关重要。本主题将深入探讨如何在Spring Boot工程中通过自定义response注解、利用Java反射机制、设置自定义拦截器以及实现...

    Java6上开发WebService的实例

    4. **使用Annotation**:Java 6引入了更多的注解,如`@WebService`、`@WebMethod`、`@WebResult`等,使得配置更加简洁,无需编写复杂的WSDL文件。 在本实例中,`wsTest01_20121107`可能是一个包含源代码和部署文件...

    关于java webservice 技术的总结

    在这个示例中,`@WebService`和`@WebMethod`注解分别用于标记整个类和服务方法。`Endpoint.publish()`方法用于发布该服务至指定URL。 ##### 2. 编译并生成客户端代码 为了能够调用上面定义的WebService,我们需要先...

    搭建WebService服务器

    接口上使用`@WebService`注解表明这是一个Web服务接口,而实现类同样使用`@WebService`注解来表示该类是接口的实现。 以下是一个示例: - **RegService接口**:定义了服务的公共方法,比如`getAll()`,返回所有...

    SpringBoot集成webService

    然后,实现这个接口,并使用`@WebServiceEndpoint`注解暴露为Web Service: ```java import org.apache.cxf.frontend.ServerFactoryBean; import javax.jws.WebService; import javax.xml.ws.Endpoint; @...

    java和.net调用webservice的各种方法总结

    【Java调用Web服务API实现】 在Java中调用Web服务主要依赖于JDK提供的Web服务API。...而在.NET环境中,使用`System.ServiceModel`可以方便地管理和调用Web服务。了解并掌握这些方法,对于跨平台的Web服务通信至关重要。

    EJB3.0容器模型的WEB服务-WebService

    1. **JAX-WS(Java API for XML Web Services)**:EJB 3.0支持JAX-WS,允许直接在Bean上使用`@WebService`注解,将Bean暴露为Web服务。服务端点接口(SEI)可以通过注解自动生成。 2. **SOAP与RESTful风格**:EJB ...

Global site tag (gtag.js) - Google Analytics