使用HttpURLConnection訪問介面進行資料處理

colorandsong發表於2014-10-29

        專案中有這樣一個場景:web工程接收到外部資料後,需要轉發給biz工程進行處理,然後biz將處理結果資料返回給web工程。為什麼要這麼做呢?是因為蛋疼的網路許可權控制,只有web工程能夠跟外部打交道,那麼問題來了,這種互動模式如何處理?

         這裡就使用到了HttpURLConnection物件,直接看如下方法吧,在web工程中使用如下:

public static String getResponseMessage(String resMsgUrl, String requestXmlData) throws IOException
    {
        // 向biz的介面發使用者的上行訊息,把requestXmlData發給biz工程的介面,這裡的resMsgUrl就是biz工程提供的url
        URL url = new URL(resMsgUrl);

        //建立連線
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

        //設定是否向HttpURLConnection輸出,因為這個是post請求,引數放在http正文內,因此需要設定為true,預設為false
        httpURLConnection.setDoOutput(true);

        //設定是否從HttpURLConnection讀入,預設為true
        httpURLConnection.setDoInput(true);

        //設定請求方法
        httpURLConnection.setRequestMethod("POST");

        //設定連線超時時間
        httpURLConnection.setConnectTimeout(5000);

        //設定讀取超時時間
        httpURLConnection.setReadTimeout(5000);

        //對請求的正文使用urlencode進行編碼
        httpURLConnection.setRequestProperty("content-type", "application/x-www-form-urlencoded");

        //一定是上面的引數設定完了之後才進行connection連線
        httpURLConnection.connect();

        //使用BufferedWriter物件進行引數寫入到正文
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8"));
        if(StringUtils.isNotEmpty(requestXmlData)){
            out.write(requestXmlData);
        }
        out.flush();
        out.close();
        int code = httpURLConnection.getResponseCode();
        String message = httpURLConnection.getResponseMessage();
        logger.info("%%%name:" + httpURLConnection.getHeaderField("name"));


        // 連線成功後,從biz的介面讀取返回的message
        if (code == 200 || message.equalsIgnoreCase("ok"))
        {
            InputStream inputStream = httpURLConnection.getInputStream();
            String resonpseMessage = readBytesFromStream(inputStream);
            inputStream.close();
            httpURLConnection.disconnect();
            return resonpseMessage;
        }
        httpURLConnection.disconnect();
        return "";
    }


   biz提供介面,先從request物件中讀出web的請求引數,然後根據引數在資料庫中找到欲返回的資訊,然後通過BufferedWriter物件寫入到response中,程式碼如下:

@RequestMapping(value="res_message.xhtml",method = RequestMethod.POST)
    public void resMessage(HttpServletRequest request, HttpServletResponse response) throws IOException{
        String requestXmlData = Util.getRequestXmlData(request);
        String resopnseXmlData =  messageService.getResponseXml(requestXmlData);
        response.setCharacterEncoding("UTF-8");
        logger.info("&&&&&&&resopnseXmlData:"+resopnseXmlData);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8"));
        out.write(resopnseXmlData);
        out.flush();
        out.close();
    }



二者的互動就完成了,值得注意的是,上述兩個方法中都涉及到了從request或InputStream中讀取資料,這裡有兩種模式:

1、按行讀取,例如:

public static String getRequestXmlData(HttpServletRequest request) throws IOException
    {
        request.setCharacterEncoding("UTF-8");
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream(), "UTF-8"));
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null)
        {
            sb.append(line);
        }
        String recievestr = sb.toString();
        return recievestr;
    }



public static String readBytesFromStream(InputStream inputStream) throws IOException
    {
        String responseStr = "";
        String totalResponseStr = "";
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((responseStr = reader.readLine()) != null)
        {
            totalResponseStr += responseStr + "\n";
        }
        return totalResponseStr;
    }

2、按規定字串長度讀取

逐位元組讀取:

public static String getRequestXmlData(HttpServletRequest request) throws IOException {
        ServletInputStream sis = request.getInputStream();
        int size = request.getContentLength()==-1?0:request.getContentLength();
        byte[] buffer = new byte[size];
        byte[] xmldataByte = new byte[size];
        int count = 0;
        int rbyte = 0;
        while (count < size) {
            rbyte = sis.read(buffer);
            for (int i = 0; i < rbyte; i++) {
                xmldataByte[count + i] = buffer[i];
            }
            count += rbyte;
        }
        return new String(xmldataByte, "UTF-8");
    }


這裡很容易出現亂碼,因為每次按長度進行讀取,如果剛好一個漢字被截斷,就會出現亂碼,因此不建議這麼使用。

public static String readBytesFromInputStream(InputStream inputStream) throws IOException
    {
        byte[] b = new byte[1024];
        String res = "";
        int bytesRead = 0;
        while (true) {
            bytesRead = inputStream.read(b, 0, 1024);
            if (bytesRead == -1) {
                return res;
            }
            res += new String(b, 0, bytesRead, "UTF-8");
         }
    }


相關文章