实现一个SOAP HttpRequst请求类

本文承接上一篇文章,路径如下:记录一个Request父类

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import jp.co.fujixerox.xcp.sdcc.store.encode.AppliDeliverB64Code;
import jp.co.fujixerox.xcp.sdcc.store.http.Requestor;
import jp.co.fujixerox.xcp.sdcc.store.log.SystemConsole;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * SSMIRequester tools class
 * 
 * @author HuangSL
 * @since 2018/05/30
 * @version 1.0.0
 * 
 */
public class SSMIRequester extends Requestor {
    private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
            .toCharArray();

    private String requesterId;
    private String requesterPassword;
    private String boundary = null;
    private Map<String, String> textParams = new HashMap<String, String>();
    private Map<String, File> fileparams = new HashMap<String, File>();

    public String getRequesterId() {
        return requesterId;
    }

    public void setRequesterId(String requesterId) {
        this.requesterId = requesterId;
    }

    public String getRequesterPassword() {
        return requesterPassword;
    }

    public void setRequesterPassword(String requesterPassword) {
        this.requesterPassword = requesterPassword;
    }

    // Add the text parameter to the form data
    public void addTextParameter(String name, String value) {
        textParams.put(name, value);
    }

    // Add a file to the form data
    public void addFileParameter(String name, File value) {
        fileparams.put(name, value);
    }

    // Clear all of the form data
    public void clearAllParameters() {
        textParams.clear();
        fileparams.clear();
    }

    /**
     * Send an soap httpRequest
     * 
     * @param target
     *            &lt;URL&gt; 接続先URL
     * @param soapAction
     *            Soap path(仕様書で指定された値)
     * @param soapRequest
     *            Soap body(指示書)
     * 
     * @return &lt;byte[]&gt; レスポンスのByte列
     * @throws Exception
     * 
     * @author HuangSL
     * @since 2018/05/30
     */
    public byte[] sendRequest(URL target, String soapAction, String soapRequest) throws Exception {
        return this.sendRequest(target, soapAction, soapRequest, false);
    }

    /**
     * 指定された接続先(LocalHost)にデータ送信しレスポンスを返す。 制限:LocalAccess限定のため、Basic認証は行わない。他のデバイスなどへのアクセスは保証しない。
     * 
     * @param target
     *            接続先URL
     * @param soapAction
     *            Soap path(仕様書で指定された値)
     * @param soapRequest
     *            Soap body(指示書)
     * @param panelAuthProperty
     *            Panel authentication flag
     * 
     * @return &lt;byte[]&gt; レスポンスのByte列
     * @throws Exception
     *             HTTPErrorException
     */
    public byte[] sendRequest(URL target, String soapAction, String soapRequest, boolean panelAuthProperty)
            throws Exception {
        SystemConsole.info("[" + this.getClass().getName()
                + ".sendRequest(target, soapAction, soapRequest, panelAuthProperty)]start!");
        SystemConsole.debug("[" + this.getClass().getName() + ".sendRequest]Parameters as below:");
        SystemConsole.debug("[" + this.getClass().getName() + ".sendRequest]target:" + target);
        SystemConsole.debug("[" + this.getClass().getName() + ".sendRequest]soapAction:" + soapAction);
        SystemConsole.debug("[" + this.getClass().getName() + ".sendRequest]soapRequest:" + soapRequest);
        SystemConsole.debug("[" + this.getClass().getName() + ".sendRequest]panelAuthProperty:" + panelAuthProperty);

        this.setDoInput(true);
        this.setDoOutpt(true);
        this.setSOAPAction(soapAction);

        HttpURLConnection httpURLConnection = (HttpURLConnection) this.openConnection(target);
        httpURLConnection.setRequestMethod("POST");
        if (this.requesterId != null && this.requesterPassword != null) {
            String basicAuth = "Basic " + AppliDeliverB64Code.encode((this.requesterId + ":" + this.requesterPassword));
            SystemConsole.info("[" + this.getClass().getName() + ".sendRequest]BasicAuth:" + basicAuth);
            httpURLConnection.setRequestProperty("Authorization", basicAuth);
        }

        // リダイレクトの許可:しない(false)
        httpURLConnection.setInstanceFollowRedirects(false);

        ByteArrayOutputStream baos = null;
        InputStream response = null;
        try {
            if (panelAuthProperty) {
                httpURLConnection.setRequestProperty("X-FX-Authorization", "panel");
            }

            // データ送信
            OutputStream writeStream = httpURLConnection.getOutputStream();
            writeStream.write(soapRequest.getBytes());
            writeStream.flush();
            writeStream.close();

            int code = httpURLConnection.getResponseCode();
            if (code != HttpURLConnection.HTTP_OK && code != HttpURLConnection.HTTP_CREATED
                    && code != HttpURLConnection.HTTP_ACCEPTED) {
                SystemConsole
                        .error("[" + this.getClass().getName() + ".sendRequest]HTTP ERROR : status code = " + code);

                if (code == 401) {
                    SystemConsole.error("[" + this.getClass().getName()
                            + ".sendRequest]HTTP Basic Authentication Error." + " requesterId:" + this.requesterId
                            + " requesterPassword:" + this.requesterPassword);

                } else if (code == 404) {
                    // SOAPサーバーが見つからない場合
                    // SOAPリクエストヘッダーが間違っていた場合でも発生するが、
                    // 市場で発生した場合はSOAPポートがOFFの場合が考えられる

                } else if (code == 500) {
                    // 内部サーバーエラー
                }

                // Get the error response even through Error happened, and then analysis the error response information
                // for some special deals.
                response = httpURLConnection.getErrorStream();
            } else {
                response = httpURLConnection.getInputStream();
            }

            baos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int len;
            while ((len = response.read(buf)) >= 0) {
                baos.write(buf, 0, len);
            }

            SystemConsole.info("[" + this.getClass().getName()
                    + ".sendRequest(target, soapAction, soapRequest, panelAuthProperty)]end!");
            return baos.toByteArray();

        } finally {

            httpURLConnection.disconnect();

            if (response != null) {
                response.close();
            }

            if (baos != null) {
                baos.close();
            }
        }
    }

    /**
     * 付属文書を伝送して、指定された接続先(LocalHost)にデータ送信しレスポンスを返す
     * 
     * @param target
     *            接続先URL
     * @param soapAction
     *            Soap path(仕様書で指定された値)
     * 
     * @return &lt;byte[]&gt; レスポンスのByte列
     * @throws Exception
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    public byte[] sendAttachmentRequest(URL target, String soapAction) throws Exception {
        SystemConsole.info("[" + this.getClass().getName() + ".sendAttachmentRequest(target, soapAction)] start!");
        SystemConsole.debug("[" + this.getClass().getName() + ".sendAttachmentRequest]Parameters as below:");
        SystemConsole.debug("[" + this.getClass().getName() + ".sendAttachmentRequest]target:" + target);
        SystemConsole.debug("[" + this.getClass().getName() + ".sendAttachmentRequest]soapAction:" + soapAction);

        HttpURLConnection conn = this.initConnection(target, soapAction);

        // リダイレクトの許可:しない(false)
        conn.setInstanceFollowRedirects(false);

        InputStream inputStream = null;
        ByteArrayOutputStream baos = null;
        try {

            conn.connect();
            OutputStream connOutStream = new DataOutputStream(conn.getOutputStream());

            writeStringParams(connOutStream);
            writeFileParams(connOutStream);
            writesEnd(connOutStream);
            connOutStream.flush();
            connOutStream.close();

            int code = conn.getResponseCode();
            if (code != HttpURLConnection.HTTP_OK && code != HttpURLConnection.HTTP_CREATED
                    && code != HttpURLConnection.HTTP_ACCEPTED) {
                SystemConsole.error("[" + this.getClass().getName()
                        + ".sendAttachmentRequest]HTTP ERROR : status code = " + code);

                if (code == 401) {
                    SystemConsole.error("[" + this.getClass().getName()
                            + ".sendAttachmentRequest]HTTP Basic Authentication Error." + " requesterId:"
                            + this.requesterId + " requesterPassword:" + this.requesterPassword);
                } else if (code == 404) {
                    // SOAPサーバーが見つからない場合
                    // SOAPリクエストヘッダーが間違っていた場合でも発生するが、
                    // 市場で発生した場合はSOAPポートがOFFの場合が考えられる

                } else if (code == 500) {
                    // 内部サーバーエラー

                }

                // Get the error response even through Error happened, and then analysis the error response information
                // for some special deals.
                inputStream = conn.getErrorStream();
            } else {
                inputStream = conn.getInputStream();
            }

            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }

            SystemConsole.info("[" + this.getClass().getName() + ".sendAttachmentRequest(target, soapAction)] end!");
            return baos.toByteArray();
        } finally {

            conn.disconnect();

            if (inputStream != null) {
                inputStream.close();
            }

            if (baos != null) {
                baos.close();
            }
        }
    }

    /**
     * Set the basic settings of the attachment request
     * 
     * @param url
     *            接続先URL
     * @param soapAction
     *            Soap path(仕様書で指定された値)
     * 
     * @return &lt;byte[]&gt; レスポンスのByte列
     * @throws Exception
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    private HttpURLConnection initConnection(URL url, String soapAction) throws Exception {
        SystemConsole.info("[" + this.getClass().getName() + ".initConnection(url, soapAction)] start!");
        SystemConsole.debug("[" + this.getClass().getName() + ".initConnection]Parameters as below:");
        SystemConsole.debug("[" + this.getClass().getName() + ".initConnection]url:" + url);
        SystemConsole.debug("[" + this.getClass().getName() + ".initConnection]soapAction:" + soapAction);

        HttpURLConnection conn = null;
        StringBuffer buf = new StringBuffer("----");
        Random rand = new Random();
        for (int i = 0; i < 15; i++) {
            buf.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
        }
        this.boundary = buf.toString();

        SystemConsole.debug("[" + this.getClass().getName() + ".initConnection]boundary:" + this.boundary);

        conn = (HttpURLConnection) this.openConnection(url);
        conn.setUseCaches(false);
        conn.setRequestProperty("Accept-Encoding", "gzip,deflate");
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("SOAPAction", soapAction);
        conn.setRequestProperty("Content-Type",
                "multipart/related; type=\"text/xml\"; start=\"<[email protected]>\"; boundary=\"" + boundary + "\"");

        if (this.requesterId != null && this.requesterPassword != null) {
            String basicAuth = "Basic " + AppliDeliverB64Code.encode((this.requesterId + ":" + this.requesterPassword));
            conn.setRequestProperty("Authorization", basicAuth);
            SystemConsole.debug("[" + this.getClass().getName() + ".initConnection]BasicAuth:" + basicAuth);
        }

        SystemConsole.info("[" + this.getClass().getName() + ".initConnection(url, soapAction)] end!");
        return conn;
    }

    /**
     * Set the text parameters to the soap request
     * 
     * @param out
     *            OutputStream
     * @throws Exception
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    private void writeStringParams(OutputStream out) throws Exception {
        SystemConsole.info("[" + this.getClass().getName() + ".writeStringParams(out)] start!");
        Set<String> keySet = textParams.keySet();
        for (Iterator<String> it = keySet.iterator(); it.hasNext();) {
            String name = it.next();
            String value = textParams.get(name);

            out.write(("\r\n").getBytes());
            out.write(("\r\n").getBytes());
            out.write(("--" + boundary + "\r\n").getBytes());
            out.write(("Content-Type: text/xml; charset=UTF-8" + "\r\n").getBytes());
            out.write(("Content-Transfer-Encoding: 8bit" + "\r\n").getBytes());
            out.write(("Content-ID: <[email protected]>" + "\r\n").getBytes());
            out.write(("\r\n").getBytes());
            out.write((value + "\r\n").getBytes());
        }
        SystemConsole.info("[" + this.getClass().getName() + ".writeStringParams(out)] end!");
    }

    /**
     * Set the attachment file to the soap request
     * 
     * @param out
     *            OutputStream
     * @throws Exception
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    private void writeFileParams(OutputStream out) throws Exception {
        SystemConsole.info("[" + this.getClass().getName() + ".writeFileParams(out)] start!");
        Set<String> keySet = fileparams.keySet();
        for (Iterator<String> it = keySet.iterator(); it.hasNext();) {
            String name = it.next();
            File value = fileparams.get(name);

            out.write(("--" + boundary + "\r\n").getBytes());
            out.write(("Content-Type: " + getContentType(value) + "; name=" + name + "\r\n").getBytes());
            out.write(("Content-Transfer-Encoding: binary" + "\r\n").getBytes());
            out.write(("Content-ID: " + "<" + name + ">" + "\r\n").getBytes());
            out.write(("Content-Disposition: attachment; name=\"" + name + "\"; filename=\"" + name + "\"\r\n")
                    .getBytes());
            out.write(("\r\n").getBytes());

            FileInputStream inStream = new FileInputStream(value);
            int bytes = 0;
            byte[] bufferByte = new byte[1024];
            while ((bytes = inStream.read(bufferByte)) != -1) {
                out.write(bufferByte, 0, bytes);
            }
            inStream.close();

            out.write(("\r\n").getBytes());
        }
        SystemConsole.info("[" + this.getClass().getName() + ".writeFileParams(out)] end!");
    }

    /**
     * Format the soap request content type
     * 
     * @param f
     *            Attachment file
     * 
     * @return &lt;String&gt;Content type
     * @throws Exception
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    private String getContentType(File f) throws Exception {
        String fileName = f.getName();
        if (fileName.endsWith(".jpg")) {
            return "image/jpeg";
        } else if (fileName.endsWith(".png")) {
            return "image/png";
        } else if (fileName.endsWith(".zip")) {
            return "application/zip";
        }
        return "application/octet-stream";
    }

    /**
     * Add the end data of the attachment soap request
     * 
     * @param out
     *            OutputStream
     * @throws Exception
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    private void writesEnd(OutputStream out) throws Exception {
        SystemConsole.info("[" + this.getClass().getName() + ".writesEnd(out)] start!");
        out.write(("--" + boundary + "--" + "\r\n").getBytes());
        out.write(("Content-Type: text/xml" + "\r\n").getBytes());
        out.write(("\r\n").getBytes());
        SystemConsole.info("[" + this.getClass().getName() + ".writesEnd(out)] end!");
    }

    /**
     * 流用メソッド
     * 
     * 引数で受け取ったbyte配列を DOMに変換する
     * 
     * @param byteArray
     *            変換したいbyte配列
     * @return Document
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    public Document byteArrayToDOM(byte[] byteArray) throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        return db.parse(new ByteArrayInputStream(byteArray));
    }

    /**
     * 流用メソッド 一部改造:Nodeが見つからなかった場合は例外を投げる 指定された文字列(target)のNodeNameに対応するNodeを取得する
     * 
     * @param nodeList
     *            取得したいNodeが含まれているNodeList
     * @param target
     *            取得したいNodeのName
     * 
     * @return 指定された文字列(target)のNodeNameに対応するNode
     * @throws Exception
     *             指定された名前のNodeが見つからなかった場合
     * 
     * @author HuangSL
     * @since 2018/05/13
     */
    public Node getNode(NodeList nodeList, String target) throws Exception {
        return this.getNode(nodeList, target, false);
    }

    /**
     * 流用メソッド一部改造:Nodeが見つからなかった場合は例外を投げる 指定された文字列(target)のNodeNameに対応するNodeを取得する
     * 
     * @param nodeList
     *            取得したいNodeが含まれているNodeList
     * @param target
     *            取得したいNodeのName
     * @param isSecond
     *            二つで取得
     * 
     * @return 指定された文字列(target)のNodeNameに対応するNode
     * @throws Exception
     *             指定された名前のNodeが見つからなかった場合
     * 
     * @author HuangSL
     * @since 2018/05/13
     */
    public Node getNode(NodeList nodeList, String target, Boolean isSecond) throws Exception {
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node.getNodeName().equals(target)) {
                if (!isSecond) {
                    return node;
                }
                isSecond = false;
            }
        }
        return null;
    }

    /**
     * NodeListから該当するNodeをListで返す
     * 
     * @param nodeList
     *            取得したいNodeが含まれているNodeList
     * @param target
     *            取得したいNodeのName
     * @return 指定された文字列(target)のNodeNameに対応するNodeList
     * @throws NodeNotFoundException
     *             指定された名前のNodeが見つからなかった場合
     * 
     * @author HuangSL
     * @since 2018/05/31
     */
    public List<Node> getNodeArray(NodeList nodeList, String target) throws Exception {
        List<Node> nodeArray = new ArrayList<Node>();

        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node.getNodeName().equals(target)) {
                nodeArray.add(node);
            }
        }
        return nodeArray;
    }
}

猜你喜欢

转载自blog.csdn.net/hsl0530hsl/article/details/80525556