2010-06-13 33 views
5

tôi cố gắng viết ứng dụng máy chủ đơn giản nhất có thể bằng Java, hiển thị biểu mẫu html với đầu vào văn bản, sau khi gửi cho tôi khả năng phân tích cú pháp xml được nhập trong văn bản đó. Còn bây giờ tôi xây dựng đơn giản ServerSocket máy chủ dựa như thế:Đọc dữ liệu POST từ biểu mẫu html được gửi tới serversocket

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(); 
    } 
} 

Sau khi hình thức (textarea với xml và một đầu vào văn bản bổ sung) được gửi trong 'bị' String kiểu biến Tôi đã urlencoded giá trị của các biến của tôi (cũng hiển thị trên màn hình, có vẻ như:

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 

Tôi có thể làm gì để thay đổi phương thức GET thành POST (nếu tôi chỉ thay đổi biểu mẫu và đặt "if (str.contains (" POST ")) { "nó cung cấp cho tôi chuỗi như

gets = POST/HTTP/1.1 

không có biến nào. Và sau đó, làm thế nào tôi có thể sử dụng xml từ trường văn bản của tôi (được gọi là 'chúng tôi')?

+0

Xin chào qqryq. Tôi có cùng mã. Bạn đã tìm ra cách đọc nội dung POST?Tôi đã cố gắng chạy thứ hai trong khi chu kỳ như cygri nói, nhưng phương thức inputStream.read hoặc bufferedReader.readline chặn chuỗi của tôi. Làm thế nào bạn đọc POST cơ thể? – Alexmelyon

+1

Ồ, tôi nhận ra! Tôi cần đọc tiêu đề "Content-Length:" và thực hiện theo chu kỳ đến độ dài này. – Alexmelyon

Trả lời

3

Dữ liệu POST không nằm trong hàng đầu tiên. In tất cả các dòng và bạn sẽ thấy. Nó thực sự ngay lập tức sau một dòng trống.

+3

ok, nhưng làm thế nào tôi có thể pront tất cả mọi thứ nếu tôi có 'while (! Str.equals ("")) {' tuyên bố? Bỏ qua dòng trống đầu tiên và dừng lại trên dòng khác? – qqryq

5

Một yêu cầu HTTP POST điển hình trông như thế này:

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 

Dòng đầu tiên chứa phương pháp này (thường là GET hoặc POST, nhưng có nhiều, như HEAD, PUT, DELETE), yêu cầu URI, và phiên bản giao thức. Sau đó, có một số tiêu đề yêu cầu, có thể không quan trọng đối với một máy chủ đơn giản. Nếu phương thức là phương thức lấy một phần thân yêu cầu (POST và PUT), thì sau khi các tiêu đề có một dòng trống, theo sau là phần thân yêu cầu. Trong trường hợp POST ở dạng HTML, nội dung sẽ bao gồm các cặp key=value cho tất cả các phần tử biểu mẫu, được nối với &. Các giá trị sẽ được mã hóa%.

Bạn chỉ cần cẩn thận phân tích cú pháp toàn bộ yêu cầu.

Bạn nên lưu ý rằng kết thúc dòng trong HTTP được cho là kiểu Windows (\r\n). Phương thức readline() có thể giải thích điều này là hai dấu ngắt dòng, vì vậy có thể có một dòng trống giữa mỗi dòng thực.

+3

ok, nhưng làm thế nào để có được dữ liệu đó khi tôi dừng lại trên dòng trống đầu tiên? – qqryq

+0

Viết lại vòng lặp while để nó không dừng trên dòng đầu tiên. Bạn có cần giúp đỡ không? – cygri

8

Đây là thực hiện của tôi cho cơ thể đọc 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()); 
} 

tôi làm điều đó cho android và publishProgres trong trường hợp của tôi có nghĩa là:

protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     instance.logTextView.append(values[0]); 
    } 
+2

Về cơ bản, Lần đọc đầu tiên sẽ lấy tất cả các dòng tiêu đề. Sau đó, tiêu đề Content-Length nên được sử dụng để biết trước số lượng ký tự cần đọc và sau đó chỉ cần chuyển sang chế độ tiếp theo – prash

4

Như có một dòng trống sau các tiêu đề, ở đây là cách tương đối đơn giản của tôi để nhận dữ liệu tải trọng bài đăng, sau khi đọc thông tin tiêu đề bằng cách sử dụng phương thức BufferReader readLine().

//socket is an instance of Socket 
InputStream is = socket.getInputStream(); 
InputStreamReader isReader = new InputStreamReader(is); 
BufferedReader br = new BufferedReader(isReader); 

//code to read and print headers 
String headerLine = null; 
    while((headerLine = br.readLine()).length() != 0){ 
     System.out.println(headerLine); 
    } 

//code to read the post payload data 
StringBuilder payload = new StringBuilder(); 
     while(br.ready()){ 
      payload.append((char) br.read()); 
      } 
System.out.println("Payload data is: "+payload.toString()) 
1

Từ this -

Chúng ta cần phải đầu đọc tiêu đề và sau đó đọc lại từ BufferedReader tương tự sử dụng chiều dài nội dung thực tế được cung cấp trong phần tiêu đề: -

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

Các vấn đề liên quan