java中注解动态传参_在WebService中使用动态代理模式和Annotation注解

公司接口程序,使用的是直接读取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 getRegionFeed();

}

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

public class HotelListAction extends BaseAction {

static {

defaultParams = new ArrayList();

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 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 newProxyInstance(Class interfaceClass,List 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 defaultParams = new ArrayList();

public void setDefaultParams(List 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...

分享到:

2011-03-17 17:59

浏览 3759

评论

2 楼

Jxdwuao

2011-05-26

我晕, 你是 .. 王雪?

1 楼

IXR

2011-05-26

  允许我转载下吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供相关的步骤和代码示例。 首先,我们需要在Spring Boot项目添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> ``` 接着,我们需要创建一个WebService,可以在Spring Boot项目创建一个新的类,例如: ```java import javax.jws.WebMethod; import javax.jws.WebService; @WebService public class MyWebService { @WebMethod public String sayHello(String name) { return "Hello, " + name + "!"; } } ``` 此时,我们已经创建了一个简单的WebService,其包含一个`sayHello`方法,用于返回传入的参数加上一句问候语。 然后,我们需要在Spring Boot项目添加一个配置类,用于配置WebService的相关信息,例如: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter; @Configuration public class WebServiceConfig { @Bean public SimpleJaxWsServiceExporter simpleJaxWsServiceExporter() { SimpleJaxWsServiceExporter exporter = new SimpleJaxWsServiceExporter(); exporter.setBaseAddress("http://localhost:8080/services/"); return exporter; } } ``` 在上述配置,我们使用了`SimpleJaxWsServiceExporter`类,它可以自动将`@WebService`注解的类发布为WebService,并且可以使用`setBaseAddress`方法设置WebService的访问地址。 最后,我们可以使用Java客户端来访问我们创建的WebService,例如: ```java import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; public class MyWebServiceClient { public static void main(String[] args) throws Exception { URL url = new URL("http://localhost:8080/services/MyWebService?wsdl"); QName qname = new QName("http://webservice.springboot.example.com/", "MyWebServiceService"); Service service = Service.create(url, qname); MyWebService myWebService = service.getPort(MyWebService.class); String result = myWebService.sayHello("World"); System.out.println(result); } } ``` 在上述代码,我们使用Java标准库的`javax.xml.ws.Service`类来访问我们创建的WebService,并且使用了`MyWebService`接口来调用`sayHello`方法。 以上就是使用Spring Boot和WebService搭建WebService服务端及使用Java客户端的简单示例,希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值