9

私は Java で可能な限り単純なサーバー アプリを作成しようとしています。HTML フォームをテキストエリア入力で表示します。送信後、そのテキストエリアに入力された xml を解析する可能性があります。今のところ、次のような単純なサーバーソケットベースのサーバーを構築します。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class WebServer {

  protected void start() {
    ServerSocket s;
    String gets = "";
    System.out.println("Start on port 80");
    try {
      // create the main server socket
      s = new ServerSocket(80);
    } catch (Exception e) {
      System.out.println("Error: " + e);
      return;
    }

    System.out.println("Waiting for connection");
    for (;;) {
      try {
        // wait for a connection
        Socket remote = s.accept();
        // remote is now the connected socket
        System.out.println("Connection, sending data.");
        BufferedReader in = new BufferedReader(new InputStreamReader(
            remote.getInputStream()));
        PrintWriter out = new PrintWriter(remote.getOutputStream());

        String str = ".";

        while (!str.equals("")) {
          str = in.readLine();
          if (str.contains("GET")){
            gets = str;
            break;
          }
        }

        out.println("HTTP/1.0 200 OK");
        out.println("Content-Type: text/html");
        out.println("");
        // Send the HTML page
        String method = "get";
        out.print("<html><form method="+method+">");
        out.print("<textarea name=we></textarea></br>");
        out.print("<input type=text name=a><input type=submit></form></html>");
        out.println(gets);
        out.flush();

        remote.close();
      } catch (Exception e) {
        System.out.println("Error: " + e);
      }
    }
  }

  public static void main(String args[]) {
    WebServer ws = new WebServer();
    ws.start();
  }
}

フォーム (xml を含むテキストエリアと 1 つの追加テキスト入力) が「gets」文字列型変数で送信された後、変数の Urlencoded 値があります (画面にも表示されます。次のようになります:

gets = GET /?we=%3Cnetwork+ip_addr%3D%2210.0.0.0%2F8%22+save_ip%3D%22true%22%3E%0D%0A%3Csubnet+interf_used%3D%22200%22+name%3D%22lan1%22+%2F%3E%0D%0A%3Csubnet+interf_used%3D%22254%22+name%3D%22lan2%22+%2F%3E%0D%0A%3C%2Fnetwork%3E&a=fooBar HTTP/1.1 

GET を POST メソッドに変更するにはどうすればよいですか (単純にフォームを変更し、" if (str.contains("POST")){" を入力すると、次のような文字列が得られます

gets = POST / HTTP/1.1

変数なし。その後、テキストエリアフィールド (「we」と呼ばれる) から xml を使用するにはどうすればよいですか?

4

5 に答える 5

9

これは、読み取り POST 本文の私の実装です。

try {
    Socket socket = params[0];
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    // read request
    String line;
    line = in.readLine();
    StringBuilder raw = new StringBuilder();
    raw.append("" + line);
    boolean isPost = line.startsWith("POST");
    int contentLength = 0;
    while (!(line = in.readLine()).equals("")) {
        raw.append('\n' + line);
        if (isPost) {
            final String contentHeader = "Content-Length: ";
            if (line.startsWith(contentHeader)) {
                contentLength = Integer.parseInt(line.substring(contentHeader.length()));
            }
        }
    }
    StringBuilder body = new StringBuilder();
    if (isPost) {
        int c = 0;
        for (int i = 0; i < contentLength; i++) {
            c = in.read();
            body.append((char) c);
            Log.d("JCD", "POST: " + ((char) c) + " " + c);
        }
    }
    raw.append(body.toString());
    publishProgress(raw.toString());
    // send response
    out.write("HTTP/1.1 200 OK\r\n");
    out.write("Content-Type: text/html\r\n");
    out.write("\r\n");
    out.write(new Date().toString());
    if (isPost) {
        out.write("<br><u>" + body.toString() + "</u>");
    } else {
        out.write("<form method='POST'>");
        out.write("<input name='name' type='text'/>");
        out.write("<input type='submit'/>");
        out.write("</form>");
    }
    //
    // do not in.close();
    out.flush();
    out.close();
    socket.close();
    //
} catch (Exception e) {
    e.printStackTrace();
    StringWriter sw = new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    publishProgress('\n' + sw.toString());
}

私はAndroidでそれを行いますpublishProgres。私の場合は次のことを意味します:

protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        instance.logTextView.append(values[0]);
    }
于 2014-02-12T13:18:52.737 に答える
6

典型的な HTTP POST リクエストは次のようになります。

POST / HTTP/1.1
Host: www.example.com
Accept: text/html,*/*;q=0.5
User-Agent: BrowserName/1.0
Referer: http://www.example.com/
Content-type: application/x-www-form-urlencoded; charset=utf-8

foo=1&bar=2

最初の行には、メソッド (通常は GET または POST ですが、HEAD、PUT、DELETE など、他にもあります)、リクエスト URI、およびプロトコル バージョンが含まれています。次に、いくつかの要求ヘッダーがありますが、単純なサーバーにとってはそれほど重要ではない場合があります。メソッドがリクエスト ボディ (POST および PUT) を受け取るメソッドの場合、ヘッダーの後に空白行があり、その後にリクエスト ボディが続きます。HTML フォームからの POST の場合、ボディはkey=valueすべてのフォーム要素のペアで構成され、&. 値は % エンコードされます。

リクエスト全体を適切に解析する必要があるだけです。

HTTP の行末は Windows スタイル ( \r\n) であることに注意してください。メソッドはこれを 2 つの改行として解釈するreadline()可能性があるため、実際の各行の間に空の行があるように見える場合があります。

于 2010-06-13T22:18:19.960 に答える
3

これから―― _

最初にヘッダーを読み取り、次にヘッダー セクションで提供される実際のコンテンツの長さを使用して、同じ BufferedReader から再度読み取る必要があります。

BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
line = in.readLine();
while ((line = in.readLine()) != null && (line.length() != 0)) {
    System.out.println("HTTP-HEADER: " + line);
    if (line.indexOf("Content-Length:") > -1) {
    postDataI = new Integer(
        line.substring(
            line.indexOf("Content-Length:") + 16,
            line.length())).intValue();
    }
}
String postData = "";
// read the post data
if (postDataI > 0) {
    char[] charArray = new char[postDataI];
    in.read(charArray, 0, postDataI);
    postData = new String(charArray);
}

HTH

于 2016-09-08T14:22:31.297 に答える
3

POST データが最初の行にありません。すべての行を印刷すると表示されます。実際には空白行の直後です。

于 2010-06-13T21:16:58.220 に答える