Web訪問http接口獲取數據-攜帶頭部消息訪問外部api-ssm框架訪問外部接口

因爲之前寫的項目中有使用到淘寶sdk中的WebUtils工具類,功能方面還是比較全,由於近期的項目又要調用外部api,在百度上面找了一圈後沒有自己喜歡的,因此在淘寶sdk中將該方法提了出來。該工具支持攜帶頭部消息(cookie等),使用起來也非常的方便。

自己只是簡單測試了一下可以使用,功能是否完全正常未知!

先看看工具類的方法吧(因爲是直接從淘寶sdk中拿過來的,所以可能有多餘無用方法,同時部分類不是從淘寶sdk中複製過來的)

調用演示

攜帶頭部消息調用演示

代碼部分

WebUtils.java




import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.GZIPInputStream;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;



/**
 * 網絡工具類。
 *
 * @author carver.gu
 * @since 1.0, Sep 12, 2009
 */
public abstract class WebUtils {

    private static final String DEFAULT_CHARSET = Constants.CHARSET_UTF8;
    private static boolean ignoreSSLCheck = true; // 忽略SSL檢查
    private static boolean ignoreHostCheck = true; // 忽略HOST檢查

    public static class TrustAllTrustManager implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    }

    private WebUtils() {
    }

    public static void setIgnoreSSLCheck(boolean ignoreSSLCheck) {
        WebUtils.ignoreSSLCheck = ignoreSSLCheck;
    }

    public static void setIgnoreHostCheck(boolean ignoreHostCheck) {
        WebUtils.ignoreHostCheck = ignoreHostCheck;
    }

    /**
     * 執行HTTP POST請求。
     *
     * @param url 請求地址
     * @param params 請求參數
     * @return 響應字符串
     */
    public static String doPost(String url, Map<String, String> params, int connectTimeout, int readTimeout) throws IOException {
        return doPost(url, params, DEFAULT_CHARSET, connectTimeout, readTimeout);
    }

    /**
     * 執行HTTP POST請求。
     *
     * @param url 請求地址
     * @param params 請求參數
     * @param charset 字符集,如UTF-8, GBK, GB2312
     * @return 響應字符串
     */
    public static String doPost(String url, Map<String, String> params, String charset, int connectTimeout, int readTimeout) throws IOException {
        return doPost(url, params, charset, connectTimeout, readTimeout, null, null);
    }

    public static String doPost(String url, Map<String, String> params, String charset, int connectTimeout, int readTimeout, Map<String, String> headerMap, Proxy proxy) throws IOException {
        String ctype = "application/x-www-form-urlencoded;charset=" + charset;
        String query = buildQuery(params, charset);
        byte[] content = {};
        if (query != null) {
            content = query.getBytes(charset);
        }
        return _doPost(url, ctype, content, connectTimeout, readTimeout, headerMap, proxy);
    }

    public static String doPost(String url, String apiBody, String charset, int connectTimeout, int readTimeout, Map<String, String> headerMap) throws IOException {
        String ctype = "text/plain;charset=" + charset;
        byte[] content = apiBody.getBytes(charset);
        return _doPost(url, ctype, content, connectTimeout, readTimeout, headerMap, null);
    }

    /**
     * 執行HTTP POST請求。
     *
     * @param url 請求地址
     * @param ctype 請求類型
     * @param content 請求字節數組
     * @return 響應字符串
     */
    public static String doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout) throws IOException {
        return _doPost(url, ctype, content, connectTimeout, readTimeout, null, null);
    }

    /**
     * 執行HTTP POST請求。
     *
     * @param url 請求地址
     * @param ctype 請求類型
     * @param content 請求字節數組
     * @param headerMap 請求頭部參數
     * @return 響應字符串
     */
    public static String doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout, Map<String, String> headerMap, Proxy proxy) throws IOException {
        return _doPost(url, ctype, content, connectTimeout, readTimeout, headerMap, proxy);
    }

    private static String _doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout, Map<String, String> headerMap, Proxy proxy) throws IOException {
        HttpURLConnection conn = null;
        OutputStream out = null;
        String rsp = null;
        try {
            conn = getConnection(new URL(url), Constants.METHOD_POST, ctype, headerMap, proxy);
            conn.setConnectTimeout(connectTimeout);
            conn.setReadTimeout(readTimeout);
            out = conn.getOutputStream();
            out.write(content);
            rsp = getResponseAsString(conn);
        } finally {
            if (out != null) {
                out.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }

        return rsp;
    }

    /**
     * 執行帶文件上傳的HTTP POST請求。
     *
     * @param url 請求地址
     * @param fileParams 文件請求參數
     * @return 響應字符串
     */
    public static String doPost(String url, Map<String, String> params, Map<String, FileItem> fileParams, int connectTimeout, int readTimeout) throws IOException {
        if (fileParams == null || fileParams.isEmpty()) {
            return doPost(url, params, DEFAULT_CHARSET, connectTimeout, readTimeout);
        } else {
            return doPost(url, params, fileParams, DEFAULT_CHARSET, connectTimeout, readTimeout);
        }
    }

    public static String doPost(String url, Map<String, String> params, Map<String, FileItem> fileParams, String charset, int connectTimeout, int readTimeout) throws IOException {
        return doPost(url, params, fileParams, charset, connectTimeout, readTimeout, null);
    }

    /**
     * 執行帶文件上傳的HTTP POST請求。
     *
     * @param url 請求地址
     * @param fileParams 文件請求參數
     * @param charset 字符集,如UTF-8, GBK, GB2312
     * @param headerMap 需要傳遞的header頭,可以爲空
     * @return 響應字符串
     */
    public static String doPost(String url, Map<String, String> params, Map<String, FileItem> fileParams, String charset,
                                int connectTimeout, int readTimeout, Map<String, String> headerMap) throws IOException {
        if (fileParams == null || fileParams.isEmpty()) {
            return doPost(url, params, charset, connectTimeout, readTimeout, headerMap, null);
        } else {
            return _doPostWithFile(url, params, fileParams, charset, connectTimeout, readTimeout, headerMap);
        }
    }

    /**
     * 執行請求
     * content_type: aplication/json
     *
     * @param url
     * @param params
     * @param charset
     * @param connectTimeout
     * @param readTimeout
     * @return
     * @throws IOException
     */
    public static String doPostWithJson(String url, Map<String, Object> params, String charset, int connectTimeout, int readTimeout) throws IOException {
        String ctype = "application/json;charset=" + charset;
        byte[] content = {};

        String body = JsonUtils.objectToJson(params);
        if (body != null) {
            content = body.getBytes(charset);
        }
        return _doPost(url, ctype, content, connectTimeout, readTimeout, null, null);
    }

    private static String _doPostWithFile(String url, Map<String, String> params, Map<String, FileItem> fileParams,
                                          String charset, int connectTimeout, int readTimeout, Map<String, String> headerMap) throws IOException {
        String boundary = String.valueOf(System.nanoTime()); // 隨機分隔線
        HttpURLConnection conn = null;
        OutputStream out = null;
        String rsp = null;
        try {
            String ctype = "multipart/form-data;charset=" + charset + ";boundary=" + boundary;
            conn = getConnection(new URL(url), Constants.METHOD_POST, ctype, headerMap, null);
            conn.setConnectTimeout(connectTimeout);
            conn.setReadTimeout(readTimeout);
            out = conn.getOutputStream();
            byte[] entryBoundaryBytes = ("\r\n--" + boundary + "\r\n").getBytes(charset);

            // 組裝文本請求參數
            Set<Entry<String, String>> textEntrySet = params.entrySet();
            for (Entry<String, String> textEntry : textEntrySet) {
                byte[] textBytes = getTextEntry(textEntry.getKey(), textEntry.getValue(), charset);
                out.write(entryBoundaryBytes);
                out.write(textBytes);
            }

            // 組裝文件請求參數
            Set<Entry<String, FileItem>> fileEntrySet = fileParams.entrySet();
            for (Entry<String, FileItem> fileEntry : fileEntrySet) {
                FileItem fileItem = fileEntry.getValue();
                if (!fileItem.isValid()) {
                    throw new IOException("FileItem is invalid");
                }
                byte[] fileBytes = getFileEntry(fileEntry.getKey(), fileItem.getFileName(), fileItem.getMimeType(), charset);
                out.write(entryBoundaryBytes);
                out.write(fileBytes);
                fileItem.write(out);
            }

            // 添加請求結束標誌
            byte[] endBoundaryBytes = ("\r\n--" + boundary + "--\r\n").getBytes(charset);
            out.write(endBoundaryBytes);
            rsp = getResponseAsString(conn);
        } finally {
            if (out != null) {
                out.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }

        return rsp;
    }

    private static byte[] getTextEntry(String fieldName, String fieldValue, String charset) throws IOException {
        StringBuilder entry = new StringBuilder();
        entry.append("Content-Disposition:form-data;name=\"");
        entry.append(fieldName);
        entry.append("\"\r\nContent-Type:text/plain\r\n\r\n");
        entry.append(fieldValue);
        return entry.toString().getBytes(charset);
    }

    private static byte[] getFileEntry(String fieldName, String fileName, String mimeType, String charset) throws IOException {
        StringBuilder entry = new StringBuilder();
        entry.append("Content-Disposition:form-data;name=\"");
        entry.append(fieldName);
        entry.append("\";filename=\"");
        entry.append(fileName);
        entry.append("\"\r\nContent-Type:");
        entry.append(mimeType);
        entry.append("\r\n\r\n");
        return entry.toString().getBytes(charset);
    }

    /**
     * 執行HTTP GET請求。
     *
     * @param url 請求地址
     * @param params 請求參數
     * @return 響應字符串
     */
    public static String doGet(String url, Map<String, String> params) throws IOException {
        return doGet(url, params, DEFAULT_CHARSET);
    }

    /**
     * 執行HTTP GET請求。
     *
     * @param url 請求地址
     * @param params 請求參數
     * @param charset 字符集,如UTF-8, GBK, GB2312
     * @return 響應字符串
     */
    public static String doGet(String url, Map<String, String> params, String charset) throws IOException {
        HttpURLConnection conn = null;
        String rsp = null;

        try {
            String ctype = "application/x-www-form-urlencoded;charset=" + charset;
            String query = buildQuery(params, charset);
            conn = getConnection(buildGetUrl(url, query), Constants.METHOD_GET, ctype, null, null);
            rsp = getResponseAsString(conn);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }

        return rsp;
    }

    private static HttpURLConnection getConnection(URL url, String method, String ctype, Map<String, String> headerMap, Proxy proxy) throws IOException {
        HttpURLConnection conn = null;
        if(proxy == null) {
            conn = (HttpURLConnection) url.openConnection();
        } else {
            conn = (HttpURLConnection) url.openConnection(proxy);
        }
        if (conn instanceof HttpsURLConnection) {
            HttpsURLConnection connHttps = (HttpsURLConnection) conn;
            if (ignoreSSLCheck) {
                try {
                    SSLContext ctx = SSLContext.getInstance("TLS");
                    ctx.init(null, new TrustManager[] { new TrustAllTrustManager() }, new SecureRandom());
                    connHttps.setSSLSocketFactory(ctx.getSocketFactory());
                    connHttps.setHostnameVerifier(new HostnameVerifier() {
                        public boolean verify(String hostname, SSLSession session) {
                            return true;
                        }
                    });
                } catch (Exception e) {
                    throw new IOException(e.toString());
                }
            } else {
                if (ignoreHostCheck) {
                    connHttps.setHostnameVerifier(new HostnameVerifier() {
                        public boolean verify(String hostname, SSLSession session) {
                            return true;
                        }
                    });
                }
            }
            conn = connHttps;
        }

        conn.setRequestMethod(method);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        if(headerMap != null && headerMap.get(Constants.TOP_HTTP_DNS_HOST) != null){
            conn.setRequestProperty("Host", headerMap.get(Constants.TOP_HTTP_DNS_HOST));
        }else{
            conn.setRequestProperty("Host", url.getHost());
        }
        conn.setRequestProperty("Accept", "text/xml,text/javascript");
        conn.setRequestProperty("User-Agent", "top-sdk-java");
        conn.setRequestProperty("Content-Type", ctype);
        if (headerMap != null) {
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                if(!Constants.TOP_HTTP_DNS_HOST.equals(entry.getKey())){
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
        }
        return conn;
    }

    private static URL buildGetUrl(String url, String query) throws IOException {
        if (StringUtils.isEmpty(query)) {
            return new URL(url);
        }

        return new URL(buildRequestUrl(url, query));
    }

    public static String buildRequestUrl(String url, String... queries) {
        if (queries == null || queries.length == 0) {
            return url;
        }

        StringBuilder newUrl = new StringBuilder(url);
        boolean hasQuery = url.contains("?");
        boolean hasPrepend = url.endsWith("?") || url.endsWith("&");

        for (String query : queries) {
            if (!StringUtils.isEmpty(query)) {
                if (!hasPrepend) {
                    if (hasQuery) {
                        newUrl.append("&");
                    } else {
                        newUrl.append("?");
                        hasQuery = true;
                    }
                }
                newUrl.append(query);
                hasPrepend = false;
            }
        }
        return newUrl.toString();
    }

    public static String buildQuery(Map<String, String> params, String charset) throws IOException {
        if (params == null || params.isEmpty()) {
            return null;
        }

        StringBuilder query = new StringBuilder();
        Set<Entry<String, String>> entries = params.entrySet();
        boolean hasParam = false;

        for (Entry<String, String> entry : entries) {
            String name = entry.getKey();
            String value = entry.getValue();
            // 忽略參數名或參數值爲空的參數
            if (StringUtils.areNotEmpty(name, value)) {
                if (hasParam) {
                    query.append("&");
                } else {
                    hasParam = true;
                }

                query.append(name).append("=").append(URLEncoder.encode(value, charset));
            }
        }

        return query.toString();
    }

    protected static String getResponseAsString(HttpURLConnection conn) throws IOException {
        String charset = getResponseCharset(conn.getContentType());
        if (conn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
            String contentEncoding = conn.getContentEncoding();
            if (Constants.CONTENT_ENCODING_GZIP.equalsIgnoreCase(contentEncoding)) {
                return getStreamAsString(new GZIPInputStream(conn.getInputStream()), charset);
            } else {
                return getStreamAsString(conn.getInputStream(), charset);
            }
        } else {
            // OAuth bad request always return 400 status
            if (conn.getResponseCode() == HttpURLConnection.HTTP_BAD_REQUEST) {
                InputStream error = conn.getErrorStream();
                if (error != null) {
                    return getStreamAsString(error, charset);
                }
            }
            // Client Error 4xx and Server Error 5xx
            throw new IOException(conn.getResponseCode() + " " + conn.getResponseMessage());
        }
    }

    public static String getStreamAsString(InputStream stream, String charset) throws IOException {
        try {
            Reader reader = new InputStreamReader(stream, charset);
            StringBuilder response = new StringBuilder();

            final char[] buff = new char[1024];
            int read = 0;
            while ((read = reader.read(buff)) > 0) {
                response.append(buff, 0, read);
            }

            return response.toString();
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
    }

    public static String getResponseCharset(String ctype) {
        String charset = DEFAULT_CHARSET;

        if (!StringUtils.isEmpty(ctype)) {
            String[] params = ctype.split(";");
            for (String param : params) {
                param = param.trim();
                if (param.startsWith("charset")) {
                    String[] pair = param.split("=", 2);
                    if (pair.length == 2) {
                        if (!StringUtils.isEmpty(pair[1])) {
                            charset = pair[1].trim();
                        }
                    }
                    break;
                }
            }
        }

        return charset;
    }

    /**
     * 使用默認的UTF-8字符集反編碼請求參數值。
     *
     * @param value 參數值
     * @return 反編碼後的參數值
     */
    public static String decode(String value) {
        return decode(value, DEFAULT_CHARSET);
    }

    /**
     * 使用默認的UTF-8字符集編碼請求參數值。
     *
     * @param value 參數值
     * @return 編碼後的參數值
     */
    public static String encode(String value) {
        return encode(value, DEFAULT_CHARSET);
    }

    /**
     * 使用指定的字符集反編碼請求參數值。
     *
     * @param value 參數值
     * @param charset 字符集
     * @return 反編碼後的參數值
     */
    public static String decode(String value, String charset) {
        String result = null;
        if (!StringUtils.isEmpty(value)) {
            try {
                result = URLDecoder.decode(value, charset);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return result;
    }

    /**
     * 使用指定的字符集編碼請求參數值。
     *
     * @param value 參數值
     * @param charset 字符集
     * @return 編碼後的參數值
     */
    public static String encode(String value, String charset) {
        String result = null;
        if (!StringUtils.isEmpty(value)) {
            try {
                result = URLEncoder.encode(value, charset);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return result;
    }

    /**
     * 從URL中提取所有的參數。
     *
     * @param query URL地址
     * @return 參數映射
     */
    public static Map<String, String> splitUrlQuery(String query) {
        Map<String, String> result = new HashMap<String, String>();

        String[] pairs = query.split("&");
        if (pairs != null && pairs.length > 0) {
            for (String pair : pairs) {
                String[] param = pair.split("=", 2);
                if (param != null && param.length == 2) {
                    result.put(param[0], param[1]);
                }
            }
        }

        return result;
    }

}

Constants.java



/**
 * 公用常量類。
 *
 * @author carver.gu
 * @since 1.0, Sep 12, 2009
 */
public abstract class Constants {

    /** TOP協議入參共享參數 **/
    public static final String APP_KEY = "app_key";
    public static final String FORMAT = "format";
    public static final String METHOD = "method";
    public static final String TIMESTAMP = "timestamp";
    public static final String VERSION = "v";
    public static final String SIGN = "sign";
    public static final String SIGN_METHOD = "sign_method";
    public static final String PARTNER_ID = "partner_id";
    public static final String SESSION = "session";
    public static final String SIMPLIFY = "simplify";
    public static final String TARGET_APP_KEY = "target_app_key";

    /** TOP協議出參共享參數 */
    public static final String ERROR_RESPONSE = "error_response";
    public static final String ERROR_CODE = "code";
    public static final String ERROR_MSG = "msg";
    public static final String ERROR_SUB_CODE = "sub_code";
    public static final String ERROR_SUB_MSG = "sub_msg";

    /** 奇門協議共享參數 */
    public static final String QIMEN_CLOUD_ERROR_RESPONSE = "response";
    public static final String QM_ROOT_TAG = "request";
    public static final String QM_CUSTOMER_ID = "customerId";
    public static final String QM_CONTENT_TYPE = "text/xml;charset=utf-8";
    public static final String QM_CONTENT_TYPE_JSON = "application/json;charset=utf-8";

    /** TOP默認時間格式 **/
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /** TOP Date默認時區 **/
    public static final String DATE_TIMEZONE = "GMT+8";

    /** UTF-8字符集 **/
    public static final String CHARSET_UTF8 = "UTF-8";

    /** HTTP請求相關 **/
    public static final String METHOD_POST = "POST";
    public static final String METHOD_GET = "GET";
    public static final String CTYPE_FORM_DATA = "application/x-www-form-urlencoded";
    public static final String CTYPE_FILE_UPLOAD = "multipart/form-data";
    public static final String CTYPE_TEXT_XML = "text/xml";
    public static final String CTYPE_APPLICATION_XML = "application/xml";
    public static final String CTYPE_TEXT_PLAIN = "text/plain";
    public static final String CTYPE_APP_JSON = "application/json";

    /** GBK字符集 **/
    public static final String CHARSET_GBK = "GBK";

    /** TOP JSON 應格式 */
    public static final String FORMAT_JSON = "json";
    /** TOP XML 應格式 */
    public static final String FORMAT_XML = "xml";

    /** TOP JSON 新格式 */
    public static final String FORMAT_JSON2 = "json2";
    /** TOP XML 新格式 */
    public static final String FORMAT_XML2 = "xml2";

    /** MD5簽名方式 */
    public static final String SIGN_METHOD_MD5 = "md5";
    /** HMAC簽名方式 */
    public static final String SIGN_METHOD_HMAC = "hmac";
    /** HMAC-SHA256簽名方式 */
    public static final String SIGN_METHOD_HMAC_SHA256 = "hmac-sha256";

    /** SDK版本號 */
    public static final String SDK_VERSION = "top-sdk-java-20190108";

    /** 異步多活SDK版本號 */
    public static final String SDK_VERSION_CLUSTER = "top-sdk-java-cluster-20190108";

    /** httpdns SDK版本號 */
    public static final String SDK_VERSION_HTTPDNS = "top-sdk-java-httpdns-20190108";

    /** httpdns SDK版本號 */
    public static final String QIMEN_SDK_VERSION_HTTPDNS = "top-qimen-sdk-java-httpdns";

    /** 響應編碼 */
    public static final String ACCEPT_ENCODING = "Accept-Encoding";
    public static final String CONTENT_ENCODING = "Content-Encoding";
    public static final String CONTENT_ENCODING_GZIP = "gzip";

    /** 默認媒體類型 **/
    public static final String MIME_TYPE_DEFAULT = "application/octet-stream";

    /** 默認流式讀取緩衝區大小 **/
    public static final int READ_BUFFER_SIZE = 1024 * 4;


    public static final String  TOP_HTTP_DNS_HOST  = "TOP_HTTP_DNS_HOST";

    /** API網關請求content type **/
    public static final String CONTENT_TYPE_XML = "xml";
    public static final String CONTENT_TYPE_JSON = "json";
    public static final String CONTENT_TYPE_FORM = "form";

    public static final String RESPONSE_TYPE_TOP = "top";
    public static final String RESPONSE_TYPE_QIMEN = "qimen1";
    public static final String RESPONSE_TYPE_QIMEN2 = "qimen2";
    public static final String RESPONSE_TYPE_DINGTALK_OAPI = "dingtalk";

    /** 釘釘調用方式 TOP標準格式,form-data */
    public static final String CALL_TYPE_TOP = "top";

    /** 釘釘調用方式 OAPI兼容格式,application/json */
    public static final String CALL_TYPE_OAPI = "oapi";
}

FileItem.java



import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 文件包裝類,支持本地文件、字節數組和輸入流三種方式。
 *
 * @author carver.gu
 * @since 1.0, Sep 12, 2009
 */
public class FileItem {

    private Contract contract;

    /**
     * 基於本地文件的構造器,適用於上傳本地文件。
     *
     * @param file 本地文件
     */
    public FileItem(final File file) {
        this.contract = new LocalContract(file);
    }

    /**
     * 基於文件絕對路徑的構造器,適用於上傳本地文件。
     *
     * @param filePath 文件絕對路徑
     */
    public FileItem(String filePath) {
        this(new File(filePath));
    }

    /**
     * 基於文件名和字節數組的構造器。
     *
     * @param fileName 文件名
     * @param content 文件字節數組
     */
    public FileItem(String fileName, byte[] content) {
        this(fileName, content, null);
    }

    /**
     * 基於文件名、字節數組和媒體類型的構造器。
     *
     * @param fileName 文件名
     * @param content 文件字節數組
     * @param mimeType 媒體類型,如:image/jpeg, text/plain
     */
    public FileItem(String fileName, byte[] content, String mimeType) {
        this.contract = new ByteArrayContract(fileName, content, mimeType);
    }

    /**
     * 基於文件名和字節流的構造器,適應於全流式上傳,減少本地內存開銷。
     *
     * @param fileName 文件名
     * @param content 文件字節流
     */
    public FileItem(String fileName, InputStream stream) {
        this(fileName, stream, null);
    }

    /**
     * 基於文件名、字節流和媒體類型的構造器,適應於全流式上傳,減少本地內存開銷。
     *
     * @param fileName 文件名
     * @param content 文件字節流
     * @param mimeType 媒體類型,如:image/jpeg, text/plain
     */
    public FileItem(String fileName, InputStream stream, String mimeType) {
        this.contract = new StreamContract(fileName, stream, mimeType);
    }

    public boolean isValid() {
        return this.contract.isValid();
    }

    public String getFileName() {
        return this.contract.getFileName();
    }

    public String getMimeType() throws IOException {
        return this.contract.getMimeType();
    }

    public long getFileLength() {
        return this.contract.getFileLength();
    }

    public void write(OutputStream output) throws IOException {
        this.contract.write(output);
    }

    private static interface Contract {
        public boolean isValid();
        public String getFileName();
        public String getMimeType();
        public long getFileLength();
        public void write(OutputStream output) throws IOException;
    }

    private static class LocalContract implements Contract {
        private File file;

        public LocalContract(File file) {
            this.file = file;
        }

        public boolean isValid() {
            return this.file != null && this.file.exists() && this.file.isFile();
        }

        public String getFileName() {
            return this.file.getName();
        }

        public String getMimeType() {
            return Constants.MIME_TYPE_DEFAULT;
        }

        public long getFileLength() {
            return this.file.length();
        }

        public void write(OutputStream output) throws IOException {
            InputStream input = null;
            try {
                input = new FileInputStream(this.file);
                byte[] buffer = new byte[Constants.READ_BUFFER_SIZE];
                int n = 0;
                while (-1 != (n = input.read(buffer))) {
                    output.write(buffer, 0, n);
                }
            } finally {
                if (input != null) {
                    input.close();
                }
            }
        }
    }

    private static class ByteArrayContract implements Contract {
        private String fileName;
        private byte[] content;
        private String mimeType;

        public ByteArrayContract(String fileName, byte[] content, String mimeType) {
            this.fileName = fileName;
            this.content = content;
            this.mimeType = mimeType;
        }

        public boolean isValid() {
            return this.content != null && this.fileName != null;
        }

        public String getFileName() {
            return this.fileName;
        }

        public String getMimeType() {
            if (this.mimeType == null) {
                return Constants.MIME_TYPE_DEFAULT;
            } else {
                return this.mimeType;
            }
        }

        public long getFileLength() {
            return this.content.length;
        }

        public void write(OutputStream output) throws IOException {
            output.write(this.content);
        }
    }

    private static class StreamContract implements Contract {
        private String fileName;
        private InputStream stream;
        private String mimeType;

        public StreamContract(String fileName, InputStream stream, String mimeType) {
            this.fileName = fileName;
            this.stream = stream;
            this.mimeType = mimeType;
        }

        public boolean isValid() {
            return this.stream != null && this.fileName != null;
        }

        public String getFileName() {
            return this.fileName;
        }

        public String getMimeType() {
            if (this.mimeType == null) {
                return Constants.MIME_TYPE_DEFAULT;
            } else {
                return this.mimeType;
            }
        }

        public long getFileLength() {
            return 0L;
        }

        public void write(OutputStream output) throws IOException {
            try {
                byte[] buffer = new byte[Constants.READ_BUFFER_SIZE];
                int n = 0;
                while (-1 != (n = stream.read(buffer))) {
                    output.write(buffer, 0, n);
                }
            } finally {
                if (stream != null) {
                    stream.close();
                }
            }
        }
    }

}

 

StringUtils.java

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 字符串工具類。
 *
 * @author carver.gu
 * @since 1.0, Sep 12, 2009
 */
public abstract class StringUtils {
    /**
     * An empty immutable <code>String</code> array.
     */
    public static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final TimeZone TZ_GMT8 = TimeZone.getTimeZone(Constants.DATE_TIMEZONE);
    private static final Pattern PATTERN_CIDR = Pattern.compile("^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/(\\d{1,2})$");
    private static final String QUOT = "&quot;";
    private static final String AMP = "&amp;";
    private static final String APOS = "&apos;";
    private static final String GT = "&gt;";
    private static final String LT = "&lt;";

    private StringUtils() {}

    /**
     * 檢查指定的字符串是否爲空。
     * <ul>
     * <li>SysUtils.isEmpty(null) = true</li>
     * <li>SysUtils.isEmpty("") = true</li>
     * <li>SysUtils.isEmpty("   ") = true</li>
     * <li>SysUtils.isEmpty("abc") = false</li>
     * </ul>
     *
     * @param value 待檢查的字符串
     * @return true/false
     */
    public static boolean isEmpty(String value) {
        int strLen;
        if (value == null || (strLen = value.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(value.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 檢查對象是否爲數字型字符串,包含負數開頭的。
     */
    public static boolean isNumeric(Object obj) {
        if (obj == null) {
            return false;
        }
        char[] chars = obj.toString().toCharArray();
        int length = chars.length;
        if(length < 1)
            return false;

        int i = 0;
        if(length > 1 && chars[0] == '-')
            i = 1;

        for (; i < length; i++) {
            if (!Character.isDigit(chars[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * 檢查指定的字符串列表是否不爲空。
     */
    public static boolean areNotEmpty(String... values) {
        boolean result = true;
        if (values == null || values.length == 0) {
            result = false;
        } else {
            for (String value : values) {
                result &= !isEmpty(value);
            }
        }
        return result;
    }

    /**
     * 把通用字符編碼的字符串轉化爲漢字編碼。
     */
    public static String unicodeToChinese(String unicode) {
        StringBuilder out = new StringBuilder();
        if (!isEmpty(unicode)) {
            for (int i = 0; i < unicode.length(); i++) {
                out.append(unicode.charAt(i));
            }
        }
        return out.toString();
    }

    /**
     * 把名稱轉換爲小寫加下劃線的形式。
     */
    public static String toUnderlineStyle(String name) {
        StringBuilder newName = new StringBuilder();
        int len = name.length();
        for (int i = 0; i < len; i++) {
            char c = name.charAt(i);
            if (Character.isUpperCase(c)) {
                if (i > 0) {
                    newName.append("_");
                }
                newName.append(Character.toLowerCase(c));
            } else {
                newName.append(c);
            }
        }
        return newName.toString();
    }

    /**
     * 把名稱轉換爲首字母小寫的駝峯形式。
     */
    public static String toCamelStyle(String name) {
        StringBuilder newName = new StringBuilder();
        int len = name.length();
        for (int i = 0; i < len; i++) {
            char c = name.charAt(i);
            if (i == 0) {
                newName.append(Character.toLowerCase(c));
            } else {
                newName.append(c);
            }
        }
        return newName.toString();
    }

    /**
     * 把字符串解釋爲日期對象,採用yyyy-MM-dd HH:mm:ss的格式。
     */
    public static Date parseDateTime(String str) {
        DateFormat format = new SimpleDateFormat(Constants.DATE_TIME_FORMAT);
        format.setTimeZone(TZ_GMT8);
        try {
            return format.parse(str);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 對日期進行字符串格式化,採用yyyy-MM-dd HH:mm:ss的格式。
     */
    public static String formatDateTime(Date date) {
        DateFormat format = new SimpleDateFormat(Constants.DATE_TIME_FORMAT);
        format.setTimeZone(TZ_GMT8);
        return format.format(date);
    }

    /**
     * 對日期進行字符串格式化,採用指定的格式。
     */
    public static String formatDateTime(Date date, String pattern) {
        DateFormat format = new SimpleDateFormat(pattern);
        format.setTimeZone(TZ_GMT8);
        return format.format(date);
    }

    /**
     * XML字符轉義包括(<,>,',&,")五個字符.
     *
     * @param value 所需轉義的字符串
     *
     * @return 轉義後的字符串 @
     */
    public static String escapeXml(String value) {
        StringBuilder writer = new StringBuilder();
        char[] chars = value.trim().toCharArray();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            switch (c) {
                case '<':
                    writer.append(LT);
                    break;
                case '>':
                    writer.append(GT);
                    break;
                case '\'':
                    writer.append(APOS);
                    break;
                case '&':
                    writer.append(AMP);
                    break;
                case '\"':
                    writer.append(QUOT);
                    break;
                default:
                    if ((c == 0x9) || (c == 0xA) || (c == 0xD) || ((c >= 0x20) && (c <= 0xD7FF))
                            || ((c >= 0xE000) && (c <= 0xFFFD)) || ((c >= 0x10000) && (c <= 0x10FFFF)))
                        writer.append(c);
            }
        }
        return writer.toString();
    }

    /**
     * 獲取類的get/set屬性名稱集合。
     *
     * @param clazz 類
     * @param isGet 是否獲取讀方法,true爲讀方法,false爲寫方法
     * @return 屬性名稱集合
     */
    public static Set<String> getClassProperties(Class<?> clazz, boolean isGet) {
        Set<String> propNames = new HashSet<String>();
        try {
            if(clazz == null){
                return propNames;
            }
            BeanInfo info = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] props = info.getPropertyDescriptors();
            for (PropertyDescriptor prop : props) {
                String name = prop.getName();
                Method method;
                if (isGet) {
                    method = prop.getReadMethod();
                } else {
                    method = prop.getWriteMethod();
                }
                if (!"class".equals(name) && method != null) {
                    propNames.add(name);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return propNames;
    }

    //-----------------------------------------------------------------------
    /**
     * <p>Checks whether the <code>String</code> contains only
     * digit characters.</p>
     *
     * <p><code>Null</code> and empty String will return
     * <code>false</code>.</p>
     *
     * @param str  the <code>String</code> to check
     * @return <code>true</code> if str contains only unicode numeric
     */
    public static boolean isDigits(String str) {
        if (StringUtils.isEmpty(str)) {
            return false;
        }
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Splits the provided text into an array, separator specified.
     * This is an alternative to using StringTokenizer.</p>
     *
     * <p>The separator is not included in the returned String array.
     * Adjacent separators are treated as one separator.
     * For more control over the split use the StrTokenizer class.</p>
     *
     * <p>A <code>null</code> input String returns <code>null</code>.</p>
     *
     * <pre>
     * StringUtils.split(null, *)         = null
     * StringUtils.split("", *)           = []
     * StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
     * StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
     * StringUtils.split("a:b:c", '.')    = ["a:b:c"]
     * StringUtils.split("a b c", ' ')    = ["a", "b", "c"]
     * </pre>
     *
     * @param str  the String to parse, may be null
     * @param separatorChar  the character used as the delimiter
     * @return an array of parsed Strings, <code>null</code> if null String input
     * @since 2.0
     */
    public static String[] split(String str, char separatorChar) {
        return splitWorker(str, separatorChar, false);
    }

    /**
     * Performs the logic for the <code>split</code> and
     * <code>splitPreserveAllTokens</code> methods that do not return a
     * maximum array length.
     *
     * @param str  the String to parse, may be <code>null</code>
     * @param separatorChar the separate character
     * @param preserveAllTokens if <code>true</code>, adjacent separators are
     * treated as empty token separators; if <code>false</code>, adjacent
     * separators are treated as one separator.
     * @return an array of parsed Strings, <code>null</code> if null String input
     */
    private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
        // Performance tuned for 2.0 (JDK1.4)

        if (str == null) {
            return null;
        }
        int len = str.length();
        if (len == 0) {
            return EMPTY_STRING_ARRAY;
        }
        List<String> list = new ArrayList<String>();
        int i = 0, start = 0;
        boolean match = false;
        boolean lastMatch = false;
        while (i < len) {
            if (str.charAt(i) == separatorChar) {
                if (match || preserveAllTokens) {
                    list.add(str.substring(start, i));
                    match = false;
                    lastMatch = true;
                }
                start = ++i;
                continue;
            }
            lastMatch = false;
            match = true;
            i++;
        }
        if (match || (preserveAllTokens && lastMatch)) {
            list.add(str.substring(start, i));
        }
        return (String[]) list.toArray(new String[list.size()]);
    }

    /**
     * Performs the logic for the <code>split</code> and
     * <code>splitPreserveAllTokens</code> methods that return a maximum array
     * length.
     *
     * @param str  the String to parse, may be <code>null</code>
     * @param separatorChars the separate character
     * @param max  the maximum number of elements to include in the
     *  array. A zero or negative value implies no limit.
     * @param preserveAllTokens if <code>true</code>, adjacent separators are
     * treated as empty token separators; if <code>false</code>, adjacent
     * separators are treated as one separator.
     * @return an array of parsed Strings, <code>null</code> if null String input
     */
    private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
        // Performance tuned for 2.0 (JDK1.4)
        // Direct code is quicker than StringTokenizer.
        // Also, StringTokenizer uses isSpace() not isWhitespace()

        if (str == null) {
            return null;
        }
        int len = str.length();
        if (len == 0) {
            return EMPTY_STRING_ARRAY;
        }
        List<String> list = new ArrayList<String>();
        int sizePlus1 = 1;
        int i = 0, start = 0;
        boolean match = false;
        boolean lastMatch = false;
        if (separatorChars == null) {
            // Null separator means use whitespace
            while (i < len) {
                if (Character.isWhitespace(str.charAt(i))) {
                    if (match || preserveAllTokens) {
                        lastMatch = true;
                        if (sizePlus1++ == max) {
                            i = len;
                            lastMatch = false;
                        }
                        list.add(str.substring(start, i));
                        match = false;
                    }
                    start = ++i;
                    continue;
                }
                lastMatch = false;
                match = true;
                i++;
            }
        } else if (separatorChars.length() == 1) {
            // Optimise 1 character case
            char sep = separatorChars.charAt(0);
            while (i < len) {
                if (str.charAt(i) == sep) {
                    if (match || preserveAllTokens) {
                        lastMatch = true;
                        if (sizePlus1++ == max) {
                            i = len;
                            lastMatch = false;
                        }
                        list.add(str.substring(start, i));
                        match = false;
                    }
                    start = ++i;
                    continue;
                }
                lastMatch = false;
                match = true;
                i++;
            }
        } else {
            // standard case
            while (i < len) {
                if (separatorChars.indexOf(str.charAt(i)) >= 0) {
                    if (match || preserveAllTokens) {
                        lastMatch = true;
                        if (sizePlus1++ == max) {
                            i = len;
                            lastMatch = false;
                        }
                        list.add(str.substring(start, i));
                        match = false;
                    }
                    start = ++i;
                    continue;
                }
                lastMatch = false;
                match = true;
                i++;
            }
        }
        if (match || (preserveAllTokens && lastMatch)) {
            list.add(str.substring(start, i));
        }
        return (String[]) list.toArray(new String[list.size()]);
    }

    /**
     * <p>Splits the provided text into an array, separators specified.
     * This is an alternative to using StringTokenizer.</p>
     *
     * <p>The separator is not included in the returned String array.
     * Adjacent separators are treated as one separator.
     * For more control over the split use the StrTokenizer class.</p>
     *
     * <p>A <code>null</code> input String returns <code>null</code>.
     * A <code>null</code> separatorChars splits on whitespace.</p>
     *
     * <pre>
     * StringUtils.split(null, *)         = null
     * StringUtils.split("", *)           = []
     * StringUtils.split("abc def", null) = ["abc", "def"]
     * StringUtils.split("abc def", " ")  = ["abc", "def"]
     * StringUtils.split("abc  def", " ") = ["abc", "def"]
     * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
     * </pre>
     *
     * @param str  the String to parse, may be null
     * @param separatorChars  the characters used as the delimiters,
     *  <code>null</code> splits on whitespace
     * @return an array of parsed Strings, <code>null</code> if null String input
     */
    public static String[] split(String str, String separatorChars) {
        return splitWorker(str, separatorChars, -1, false);
    }

    /**
     * 判斷指定的IP地址是否在IP段裏面。
     *
     * @param ipAddr IP地址
     * @param cidrAddr 用CIDR表示法的IP段信息
     * @return true/false
     */
    public static boolean isIpInRange(String ipAddr, String cidrAddr) {
        Matcher matcher = PATTERN_CIDR.matcher(cidrAddr);
        if (!matcher.matches()) {
            throw new IllegalArgumentException("Invalid CIDR address: " + cidrAddr);
        }

        int[] minIpParts = new int[4];
        int[] maxIpParts = new int[4];
        String[] ipParts = matcher.group(1).split("\\.");
        int intMask = Integer.parseInt(matcher.group(2));

        for (int i = 0; i < ipParts.length; i++) {
            int ipPart = Integer.parseInt(ipParts[i]);
            if (intMask >= 8) {
                minIpParts[i] = ipPart;
                maxIpParts[i] = ipPart;
                intMask -= 8;
            } else if (intMask > 0) {
                minIpParts[i] = ipPart >> intMask;
                maxIpParts[i] = ipPart | (0xFF >> intMask);
                intMask = 0;
            } else {
                minIpParts[i] = 1;
                maxIpParts[i] = 0xFF - 1;
            }
        }

        String[] realIpParts = ipAddr.split("\\.");
        for (int i = 0; i < realIpParts.length; i++) {
            int realIp = Integer.parseInt(realIpParts[i]);
            if (realIp < minIpParts[i] || realIp > maxIpParts[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 將列表中的對象連接成字符串
     *
     * @param objs
     * @param sep
     * @return
     */
    public static String join(Iterable<?> objs, String sep) {
        StringBuilder buf = new StringBuilder();

        join(buf, objs, sep);

        return buf.toString();
    }

    /** 將列表中的對象連接起來。 */
    public static void join(StringBuilder buf, Iterable<?> objs, String sep) {
        try {
            join((Appendable) buf, objs, sep);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /** 將列表中的對象連接起來。 */
    public static void join(Appendable buf, Iterable<?> objs, String sep) throws IOException {
        if (objs == null) {
            return;
        }

        if (sep == null) {
            sep = "";
        }

        for (Iterator<?> i = objs.iterator(); i.hasNext();) {
            buf.append(String.valueOf(i.next()));

            if (i.hasNext()) {
                buf.append(sep);
            }
        }
    }
}

 

JsonUtils.java

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

public class JsonUtils {

    // 定義jackson對象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 將對象轉換成json字符串。
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 將json結果集轉化爲對象
     *
     * @param jsonData json數據
     * @param
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 將json數據轉換成pojo對象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

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