搭建本地server,響應Android客戶端HTTP請求

Dusan_杜小菜發表於2016-05-03

有些時候,我們可能需要自己搭建本地伺服器,來測試某個客戶端功能(公共API不滿足自己需要的情況下),如果自己寫介面,寫在servlet中方便點。本文以普通的get,post請求為例,分享下如何搭建本地Server(Tomcat+servlet),測試網路請求,並演示HttpURLConnection的使用。

一,安裝Eclipse for JavaEE

官方下載:http://www.eclipse.org/downloads/
直接傻瓜安裝,另外自行安裝jdk,tomcat。

二,建立server專案

1,執行Eclipse,File->Dynamic Web project

Create a standalone Dynamic Web project or add it to a new or existing Enterprise Application.

2,新建servlet,配置web.xml

新建LoginServlet,如果報錯,自行匯入servlet庫(專案屬性->Build Path->add Libraries),安裝了tomact也有這個。
檢視配置檔案,位於專案根目錄WEB-INF/web.xml,確保有url對映。

  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/servlet/LoginServlet</url-pattern>
  </servlet-mapping>

3,寫服務端程式碼,根據引數返回json

public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String username = request.getParameter("username");
        if(username!=null&&!"".equals(username)){
            String result = "\""+username+"\"";
            out.write("{\"username\":"+result+"}");
            return;
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            doGet(request, response);
    }
}

如果寫在jsp裡面,可以這樣:

<body>
  <!--
    歡迎您!測試JSP,duqian
    -->
    <%
    String name=request.getParameter("username");
    String age=request.getParameter("age");
    out.println("使用者名稱="+name+",年齡="+age);
    %>
  </body>

三,建立android專案

使用android stduio 建立簡單的工程。訪問上面建立的servlet,如果是真機,需要改localhost為pc的IP地址。
別忘了許可權:

 <uses-permission  android:name="android.permission.INTERNET"/>

我使用HttpURLConnection演示請求的過程,不建議使用httpClinet,android 6.0已經廢棄它了,要使用必需新增依賴:

useLibrary 'org.apache.http.legacy'//android 6.0(api23) 後,不再提供org.apache.http.*(只保留幾個類).

如果是請求一個jsp頁面,將返回整個頁面的原始碼。以上servlet僅僅out.write一個字串,所以客戶端接受到的只有json字串。程式碼如下:

 public static void testHttpURLConnection() {
        // 1.獲取請求的路徑:改成你自己的
        //final String path ="http://192.168.10.245:8080/Android/index.jsp?username=duqian&age=25";//get
        final String path ="http://192.168.100.47:8080/Android/servlet/LoginServlet";//post
        HttpURLConnection conn = null;
        InputStream is = null;
        try {
            // 2.獲取url物件
            URL url = new URL(path);
            // 3.得到連線的物件
            conn = (HttpURLConnection) url.openConnection();
            // 4.設定連線的引數
            // 設定請求方式
            //conn.setRequestMethod("GET");
            conn.setRequestMethod("POST");
            // 設定連線超時時間
            conn.setConnectTimeout(5000);
            // 設定讀取資料的超時時間
            conn.setReadTimeout(5000);
            conn.setUseCaches(false);// Post 請求不能使用快取
            // 設定允許讀取伺服器端返回的資料
            conn.setDoInput(true);
            // 5.連線伺服器
            //conn.connect();//如果是post請求,不要加這個,否則可能IllegalStateException: Already connected
            //如果是get請求,引數寫url中,就不需要post引數
            conn.setDoOutput(true);//4.0中設定httpCon.setDoOutput(true),將導致請求以post方式提交
            final OutputStream outputStream = conn.getOutputStream();
            outputStream.flush();
            outputStream.write("username=dusan".getBytes("UTF-8"));
            outputStream.close();
            // 6.獲取返回的伺服器端的響應碼。
            int responseCode = conn.getResponseCode();
            // 7.只有響應碼是200時,方可正常讀取
            if (200==responseCode) {
                is = conn.getInputStream();
                // 將獲取的輸入流中的資料轉換為字串
                final String content=StreamTools.readStream(is);
                   LogUtils.debug(TAG,"content="+content);
            }else{
                LogUtils.debug(TAG,"responseCode="+responseCode);
            }
        }catch (Exception e){
            LogUtils.debug(TAG,e.toString());
        }
    }

將接受到的位元組流轉化成字串,UTF-8編碼格式。

public static String readStream(InputStream in) throws Exception{
         ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
         int len = -1;
         byte buffer[] = new byte[1024];
         while((len=in.read(buffer))!=-1){
             baos.write(buffer, 0, len);
         }
         in.close();
        return new String(baos.toByteArray(),"UTF-8");
        //return new String(baos.toByteArray());

    }

以上程式碼,get和post請求寫在了一起,並且jsp和servet頁面都有測試。如果是get請求,就把引數寫在url地址上面,否則以流的形式向服務端傳送。
servlet返回的形式,通常的介面都以json格式返回result,方便解析處理。如:

{"name":"duqian-291902259"}

四,總結

如果自己寫介面,寫在servlet中方便點,如果寫在jsp返回的是全面頁面內容。多個引數也一樣處理。
杜乾,Dusan,Q 291902259,歡迎交流。

相關文章