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); }
}