webServie的RESTful类型客户端
1 在web项目中定义所有Action的父类,我们项目使用的是struts1.1
public abstract class BaseAction extends DispatchAction{ protected final RSClient client = ClientFactory.getRRSClient();//Restful Service Client }
2 具体Action类
public class WebDutyAction extends BaseAction { // 定义WebService服务接口 private IWebDutyWS webDutyWSClient; // 初始化WebService服务接口 public WebDutyAction() { this.webDutyWSClient = client.createObject(IWebDutyWS.class); } //方法中调用WebService服务(伪代码) { DictItemBean dictItemGtacBean = new DictItemBean(); List<DictItemBean> dictGtacList = webDutyWSClient.getDictItemList(dictItemGtacBean); } }
web项目结束,重点在使用的API包中
----------------------------------------------
3 在SupportWS-RS-API项目包中定义 RSClient
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.transport.http.HTTPConduit; public class RSClient { /** * Rest WebService服务发布路径 */ private final String baseAddress; /** * 服务端认证用户名 */ private String username; /** * 服务端认证密码 */ private String password; /** * HTTP Body实体提供者 */ private List providers = new ArrayList(); /** * HTTP Header头部属性 */ private Map<String, String> headers = new HashMap<String, String>(); RSClient(String baseUrl) { this.baseAddress = baseUrl; } RSClient(String baseUrl, List<?> providers) { this.baseAddress = baseUrl; this.providers = providers; } RSClient(String baseUrl, List<?> providers, Map<String, String> headers) { this.baseAddress = baseUrl; this.providers = providers; this.headers = headers; } /****************************** 设置用户名和密码 ****************************/ public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } /****************************** 设置实体提供者 ****************************/ public void addProvider(Object provider) { providers.add(provider); } public void removeProvider(Object provider) { providers.remove(provider); } public void clearProviders() { providers.clear(); } /****************************** 设置HTTP头部属性 ****************************/ public void setHeader(String key, String value) { headers.put(key, value); } public void clearHeaders() { headers.clear(); } /*创建JAX-RS客户端接口代理*/ public <T> T createObject(Class<T> cls) { return createObject(cls, headers); } /* 创建JAX-RS客户端接口代理,且设置等待超时时间*/ public <T> T createObject(Class<T> cls, long receiveTimeout) { T wsclient = createObject(cls, headers); HTTPConduit conduit = WebClient.getConfig(wsclient).getHttpConduit(); conduit.getClient().setReceiveTimeout(receiveTimeout); return wsclient; } /** * 创建JAX-RS客户端接口代理,且设置HTTP头部属性*/ public <T> T createObject(Class<T> cls, Map<String, String> headers) { JAXRSClientFactoryBean factory = new JAXRSClientFactoryBean(); factory.setAddress(baseAddress); factory.setUsername(username); factory.setPassword(password); factory.setServiceClass(cls); factory.setProviders(providers); factory.setInheritHeaders(true); factory.setHeaders(headers); return cls.cast(factory.create()); } }
4 定义BaseAction中获取RSClient的资源管理类
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType;
public class ClientFactory { /*安全认证用户名*/ public static final String WS_USERNAME = Constansts.WS_USERNAME; /* 安全认证密码*/ private static final String WS_PASSWORD = getPassword(); /* 当前时间,以检查是否重新加载配置文件*/ private static long CUR_TIME = System.currentTimeMillis(); /*Restful WebService 客户端*/ private static RSClient client = null; /* 获取Restful WebService 客户端*/ public static synchronized RSClient getRRSClient() { if ((null == client) || isNeedRefresh()) { String serverUrl = getServerUrl(); Map<String, String> headers = new HashMap<String, String>();
ArrayList list=Arrays.asList(new ResponseApplicationExceptionMapper(),new ResponseSearchExceptionMapper(),new MapMessageBodyReader(),
new MapMessageBodyWriter(),new StringListMessageBodyReader(),new StringListMessageBodyWriter(),new DataHandlerMessageBodyReader(),
new DataHandlerMessageBodyWriter());
headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
client = RSClientFactory.createJAXRSClient(serverUrl,list,headers); //从RSClient工厂类获取client client.setUsername(WS_USERNAME); client.setPassword(WS_PASSWORD); } return client; } /*从配置文件中加载认证用户名和密码*/ private static String getPassword() { String password = PropertyReader.createPropertyReader(Constansts.WSS_FILENAME) .getProperty(Constansts.WS_USERNAME); if (StringUtil.isNullOrEmpty(password)) { throw new NullPointerException("Get Password Error,Password must not be empty!"); } return password; } /* 从配置文件中加载WebService服务发布地址*/ private static String getServerUrl() { String serverUrl = PropertyReader.createPropertyReader(Constansts.WSS_FILENAME) .getProperty(Constansts.WS_SERVERURL); if (StringUtil.isNullOrEmpty(serverUrl)) { throw new NullPointerException("Get ServerUrl Error,ServerUrl must not be empty!"); } return serverUrl; } /*检查是否需要自动重新加载配置文件,每隔30分钟重新加载配置文件*/ private static boolean isNeedRefresh() { long curTime = System.currentTimeMillis(); if (curTime - CUR_TIME > Constansts.INTERVAL_TIME) { CUR_TIME = curTime; return true; } return false; } }
5 RSClient工厂创建类 用来缓存和客户端并只保留一份
public class RSClientFactory { private static Map<String, Object> pools = new HashMap<String, Object>(); public static synchronized RSClient createJAXRSClient(String url) { if (null == pools.get(url)) { RSClient client = new RSClient(url); pools.put(url, client); } return (RSClient) pools.get(url); } public static synchronized RSClient createJAXRSClient(String url, List<?> providers) { if (null == pools.get(url)) { RSClient client = new RSClient(url, providers); pools.put(url, client); } return (RSClient) pools.get(url); } public static synchronized RSClient createJAXRSClient(String url, List<?> providers, Map<String, String> headers) { if (null == pools.get(url)) { RSClient client = new RSClient(url, providers, headers); pools.put(url, client); } return (RSClient) pools.get(url); } }
完成-------------------客户端实例用来保存ws路径,登录名,密码,http的 body providers和 http headers。当要具体生成一个代理对象时,才用cfx进行代理接口封装
备注1 资源文件读取类
import java.util.Properties; public class PropertyReader { private static Properties properties = new Properties(); private static Object lock = new Object(); private PropertyReader(){} public static PropertyReader createPropertyReader(String filePath) { if (StringUtil.isNullOrEmpty(filePath)) { throw new IllegalArgumentException("file path must not be empty."); } PropertyReader reader = new PropertyReader(); reader.load(filePath); return reader; } private void load(String filePath) throws ExceptionInInitializerError { synchronized (lock) { InputStream in = null; try { in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath); properties.load(in); } catch (IOException e) { throw new ExceptionInInitializerError(e); } finally { try { if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } } } public String getProperty(String key) { return properties.getProperty(key); }
}