CXF+SpringBoot 搭建客戶端調用第三方CXF服務

開門見山CXF 一個webService框架,一般互聯網基本使用Http+Json 來交互數據,但是國家項目例如稅局、電網、銀行使用CXF 還有很多。原因估計是因爲他們需要給不同開發語言提供服務。這樣CXF 價值體現出來。那麼我們今天剛好需要調用別人的CXF服務。目前我們使用的是SpringBoot 所以從導入cxf jar 開始。

  • 配置pom.xml 一個是基本jar 一個安全認證jar
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
			<version>3.2.4</version>
    		</dependency>
        <dependency>
          <groupId>org.apache.cxf</groupId>
          <artifactId>cxf-rt-ws-security</artifactId>
          <version>3.2.4</version>
      </dependency>
  • 工具類 這個方法主要通過加載配置文件獲取文件的值。
public class CXFUtils {
    private static final Logger log = LoggerFactory.getLogger(CXFUtils.class);
    private static Properties keyStoreProperties = null;
    private static final String keyStoreConfigFilePath = "you.properties";

    public static Properties getKeyStoreConfigFile() {
        if (keyStoreProperties == null) {
            keyStoreProperties = new Properties();
            InputStream in = WebServiceCXFTest.class.getClassLoader().getResourceAsStream(keyStoreConfigFilePath);
            try {
                keyStoreProperties.load(in);
            } catch (IOException e) {
                log.error("keyStore配置文件加載失敗.");
            }
        }
        return keyStoreProperties;
    }
}
  • 實現CallbackHandler 回調接口 主要認證通過設置密碼passwd is the password associated to the identifier, 在創建動態客戶端 中會使用
public class WSAuthHandler implements CallbackHandler {
	@Override
	public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
		Properties keyStoreConfigFile = CXFUtils .getKeyStoreConfigFile();
		
		for (int i = 0; i < callbacks.length; i++) {
			WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
			// 這裏必須設置密碼,否則會拋出:java.lang.IllegalArgumentException: pwd == null
			// but a password is needed
			pc.setPassword(keyStoreConfigFile.getProperty("org.apache.ws.security.crypto.merlin.alias.password"));
		}
	}
	
}
  • 創建動態客戶端 這個核心就是需要訪問兼容Https 請求。
  public static Client getClient() {
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Properties keyStoreConfigFile = getKeyStoreConfigFile();
        Client client = dcf.createClient(keyStoreConfigFile.getProperty("bjtax.wss.wsdlUrl"));
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setAutoRedirect(true);//不設置 將報錯重定向
        conduit.setClient(httpClientPolicy);
        Map<String, Object> outProps = new HashMap<String, Object>();
        outProps.put(ConfigurationConstants.ACTION, ConfigurationConstants.USERNAME_TOKEN + " "
                + ConfigurationConstants.SIGNATURE + " " + ConfigurationConstants.TIMESTAMP);//這個和第三方配置一致就可以
        outProps.put(ConfigurationConstants.USER, keyStoreConfigFile.getProperty("bjtax.wss.username"));//第三方分配的用戶
        outProps.put(ConfigurationConstants.SIGNATURE_USER, keyStoreConfigFile.getProperty("bjtax.wss.signature.user"));//簽名用戶
        outProps.put(ConfigurationConstants.SIG_KEY_ID,
                keyStoreConfigFile.getProperty("bjtax.wss.signatureKeyIdentifier"));
        outProps.put(ConfigurationConstants.PASSWORD_TYPE, keyStoreConfigFile.getProperty("bjtax.wss.passwordType"));
        outProps.put(ConfigurationConstants.PW_CALLBACK_CLASS,
                keyStoreConfigFile.getProperty("bjtax.wss.passwordCallbackClass"));//回調方法
        outProps.put(ConfigurationConstants.SIG_PROP_FILE, keyStoreConfigFilePath);//jsk 認證文件
        WSS4JOutInterceptor wss4jOut = new WSS4JOutInterceptor(outProps);
        client.getOutInterceptors().add(wss4jOut);
        return client;
    }

  • 解析xml 和實體轉化
public class XStreamConvertor<T extends Mto> {
	
	private static Map<String,XStreamMarshaller> xstreamCache = new ConcurrentHashMap<String,XStreamMarshaller>();
	private static final String XML_TAG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<tiripPackage xsi:type=\"tiripPackage\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.chinatax.gov.cn/dataspec/\">";
	private static final String GBK = "UTF-8";
	public String toXml(T pojo) throws BusinessException {
		String clzName = pojo.getClass().getName();
		XStreamMarshaller xstreamMarshaller = xstreamCache.get(clzName);
		if(xstreamMarshaller == null) {
			xstreamMarshaller = new XStreamMarshaller();
			xstreamMarshaller.setEncoding(GBK);
			xstreamMarshaller.setStreamDriver(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));
			xstreamCache.put(clzName, xstreamMarshaller);
		}
		XStream xStream = xstreamMarshaller.getXStream();
		xStream.processAnnotations(pojo.getClass());
		return XML_TAG + xStream.toXML(pojo).replaceAll("<tiripPackage>", "").replaceAll("&quot;", "\"");
	}
	
	@SuppressWarnings("unchecked")
	public T fromXml(Class<T> clz,String xml) {
		String clzName = clz.getName();
		XStreamMarshaller xstreamMarshaller = xstreamCache.get(clzName);
		if(xstreamMarshaller == null) {
			xstreamMarshaller = new XStreamMarshaller();
			xstreamMarshaller.setEncoding(GBK);
			xstreamMarshaller.setStreamDriver(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));
			xstreamCache.put(clzName, xstreamMarshaller);
		}
		XStream xStream = xstreamMarshaller.getXStream();
		xStream.setClassLoader(clz.getClassLoader());
		xStream.processAnnotations(clz);
		return (T) xStream.fromXML(xml);
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章