2010-11-30 47 views
1

我有獨立的Java客戶端使用httpURLconnection類將http數據發送到http servlet。但數據以非可打印字符格式顯示。將HTTP數據從HTTP Java客戶端發送到具有HttpURLConnection的servlet時出現問題

對於模擬我一直試圖發送簡單的字符串,但它仍然出現在非打印格式。

我寫了下面的客戶端代碼的servlet進行溝通,

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 
import java.net.HttpURLConnection; 
import java.net.ProtocolException; 
import java.net.URL; 

public class HttpClient implements IClient { 

    private static IClient client = null; 

    private HttpURLConnection httpConn = null; 

    private OutputStream output = null; 

    private InputStream input = null; 

    private OutputStreamWriter out = null; 

    private HttpClient() { 
    } 

    public static IClient getHttpClient() { 
     if (client == null) { 
      client = new HttpClient(); 
     } 
     return client; 
    } 

    @Override 
    public void connect(String urlString) throws IOException { 
     URL url = new URL(urlString); 
     httpConn = (HttpURLConnection) url.openConnection(); 
     initConnection(); 
     httpConn.connect(); 
     output = httpConn.getOutputStream(); 
     input = httpConn.getInputStream(); 
     System.out.println("Connection Response:" + httpConn.getResponseCode()); 
    } 

    @Override 
    public void sendFile(File file) throws IOException { 
     // BufferedOutputStream bos = new BufferedOutputStream(output); 
     // InputStream fis = new FileInputStream(file); 
     // int bytesRead = 0; 
     // byte[] buffer = new byte[8192]; 
     // while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { 
     // bos.write(buffer, 0, bytesRead); 
     // System.out.println("write:"+buffer); 
     // } 
     // bos.close(); 
     // fis.close(); 

     OutputStreamWriter out = new OutputStreamWriter(output, "UTF-16"); 
     out.write("test me"); 
    } 

    @Override 
    public boolean isConnected() { 
     return httpConn != null ? true : false; 
    } 

    @Override 
    public void close() { 
     httpConn.disconnect(); 
    } 

    private void initConnection() throws ProtocolException { 
     httpConn.setDoOutput(true); 
     httpConn.setDoInput(true); 
     httpConn.setRequestMethod("POST"); 
     httpConn.setUseCaches(false); 
     httpConn.setRequestProperty("Content-Type", 
       "text/xml; charset=\"UTF-16\""); 
     httpConn.setRequestProperty("Connection", "Keep-Alive"); 

    } 

    private static byte[] getBytesFromFile(File file) throws IOException { 

     InputStream is = new FileInputStream(file); 
     System.out.println("\nDEBUG: FileInputStream is " + file); 

     // Get the size of the file 
     long length = file.length(); 
     System.out.println("DEBUG: Length of " + file + " is " + length + "\n"); 

     /* 
     * You cannot create an array using a long type. It needs to be an int 
     * type. Before converting to an int type, check to ensure that file is 
     * not loarger than Integer.MAX_VALUE; 
     */ 
     if (length > Integer.MAX_VALUE) { 
      System.out.println("File is too large to process"); 
      return null; 
     } 

     // Create the byte array to hold the data 
     byte[] bytes = new byte[(int) length]; 

     // Read in the bytes 
     int offset = 0; 
     int numRead = 0; 
     while ((offset < bytes.length) 
       && ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) { 

      offset += numRead; 

     } 

     // Ensure all the bytes have been read in 
     if (offset < bytes.length) { 
      throw new IOException("Could not completely read file " 
        + file.getName()); 
     } 

     return bytes; 

    } 

} 

和servlet代碼如下,

import java.io.BufferedInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public class XMLServlet extends HttpServlet { 

    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException { 
     doPost(req, resp); 
    } 

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException { 
     System.out.println("=========inside doPost========="); 
//  BufferedInputStream bis = new BufferedInputStream(req.getInputStream()); 
//  OutputStream fos = new FileOutputStream("test.xml"); 
//  int bytesRead = 0; 
//  byte[] buffer = new byte[8192]; 
//  while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) { 
//   System.out.println("read:"+buffer); 
//   fos.write(buffer, 0, bytesRead); 
//  } 
//  fos.close(); 
//  bis.close(); 
//  

     req.setCharacterEncoding("UTF-16"); 
     InputStreamReader isr = new InputStreamReader(req.getInputStream(),"UTF-16"); 
     char[] data = new char[10]; 
     isr.read(data); 
     System.out.println(data); 
     for (char c : data) { 
      System.out.println(c); 
     } 
    } 

} 

請任何幫助我走出這個問題。

+0

我喜歡`return httpConn!= null? true:false;`:) – khachik 2010-11-30 16:09:42

回答

2

我認爲你過於複雜。我只寫了類似的東西,它接受任何文件並通過HTTP將它傳輸到一個servlet。請記住:所有數據都是二進制的(包括文本文件) - 期間。這取決於給定的應用程序來解釋該二進制數據。例如,notepad.exe只是讀取一組二進制數據並嘗試使用ASCII標準對其進行格式化。因此,瞭解這一點,只需使用原始流讀取文件,將連接的MIME類型設置爲application/octet-stream並通過「PUT」方法發送。 servlet代碼應該使用請求中的原始InputStream讀取文件,並在其空間中創建相應的文件。

從客戶端代碼:

URL url = new URL(urlString); 
HttpURLConnection cnx = (HttpURLConnection)url.openConnection(); 
cnx.setRequestMethod("PUT"); 
cnx.setRequestProperty("Content-Type", "application/octet-stream"); 
// optional request property 
cnx.setRequestProperty("filename", filename); 
cnx.setDoOutput(true); 
cnx.connect(); 
BufferedInputStream fileIn = 
     new BufferedInputStream(new FileInputStream(fileName), BUFFER_SIZE); 
BufferedOutputStream out = 
     new BufferedOutputStream(cnx.getOutputStream(), BUFFER_SIZE); 
byte[] bytes = new byte[BUFFER_SIZE]; 
int bytesRead; 
while((bytesRead = fileIn.read(bytes)) != -1){ 
    out.write(bytes, 0, bytesRead); 
} 

就是這樣。

現在servlet代碼....

public void doPut(HttpServletRequest request, HttpServletResponse response){ 
    String filename = (String)request.getHeader("filename"); 
    StringBuilder fullPath = new StringBuilder(100); 
    ServletContext ctxt = getServletContext(); 
    fullPath.append(ctxt.getRealPath("")) 
     .append("uploads\\").append(filename); 
    File f = new File(fullPath.toString()); 
    f.createNewFile(); 
    InputStream in = request.getInputStream(); 
    BufferedOutputStream fileOut = 
     new BufferedOutputStream(new FileOutputStream(f)); 
    byte[] bytes = new byte[BUFFER_SIZE]; 
    int bytesRead; 
    while((bytesRead = in.read(bytes)) != -1){ 
     fileOut.write(bytes, 0, bytesRead); 
    } 
    fileOut.flush(); 
    fileOut.close(); 
    response.setStatus(HttpServletResponse.SC_CREATED); 
} 
0

我有獨立的java客戶端使用httpURLconnection類將數據發送到http servlet。但數據以非打印字符格式顯示。

我能理解。您將數據作爲UTF-16發送,但XML文件本身可能不會以UTF-16格式保存。您需要使用與保存XML文件相同的字符編碼。通常是UTF-8。

對於模擬我一直試圖發送簡單的字符串,但它仍然出現在非打印格式。

我不明白。它應該像你在代碼中一樣工作。可能你沒有正確測試它。

1

主要有兩種方式來上傳文件到服務器使用HTTP方法:

  1. 上傳使用PUT方法的文件。這使您可以將一個文件一次放到服務器上。 PUT方法很容易實現,但不能使用PUT方法從HTML表單上傳文件(例如,在Web瀏覽器中上傳表單)。

  2. 使用POST方法上傳文件。這是更復雜的,但大多數網站使用它來上傳文件到服務器。您可以爲每個請求執行多個文件上傳。這就是我要談論的內容。

注意:GET不用於文件上傳,除非您以某種方式進行編碼。

使用URLConnection上傳文件不是直截了當的,需要您準備「multipart form」中的數據。當然,你不應該自己動手。有很多圖書館可以爲你處理這個問題,例如HttpClient。如果您真的想使用URLConnection,我會參考上一個關於「How to use java.net.URLConnection to fire and handle HTTP requests」的問題

下面是使用HttpClient上傳文件的代碼。它從HttpClient示例代碼簡化。

import java.io.File; 


import org.apache.commons.httpclient.HttpClient; 
import org.apache.commons.httpclient.HttpStatus; 
import org.apache.commons.httpclient.methods.PostMethod; 
import org.apache.commons.httpclient.methods.multipart.FilePart; 
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; 
import org.apache.commons.httpclient.methods.multipart.Part; 
import org.apache.commons.httpclient.params.HttpMethodParams; 

public class MultipartFileUploadApp { 

    public static void main(String[] args) { 
     String targetURL = "http://localhost:8080/yourserver/upload"; 
     File targetFile = new File("/path/to/your/file.txt"); 

     PostMethod filePost = new PostMethod(targetURL); 

     filePost.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, false); 

     try { 

      System.out.println("Uploading " + targetFile.getName() + " to " + targetURL); 

      // add more parts you want to upload multiple files. 
      Part[] parts = {new FilePart(targetFile.getName(), targetFile)}; 

      filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams())); 

      HttpClient client = new HttpClient(); 
      client.getHttpConnectionManager().getParams().setConnectionTimeout(5000); 

      int status = client.executeMethod(filePost); 

      if (status == HttpStatus.SC_OK) { 
       System.out.println("Upload complete, response=" + filePost.getResponseBodyAsString()); 
      } else { 
       System.out.println("Upload failed, response=" + HttpStatus.getStatusText(status)); 
      } 
     } catch (Exception ex) { 
      System.out.println("Error: " + ex.getMessage()); 
      ex.printStackTrace(); 
     } finally { 
      filePost.releaseConnection(); 
     } 


    } 
} 

對於服務器端,您必須解析多部分表單請求。當然,有些圖書館可以爲你做到這一點。這裏是我使用的snipplet

import java.io.File; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.util.Iterator; 
import java.util.List; 

import javax.servlet.ServletConfig; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.commons.fileupload.FileItem; 
import org.apache.commons.fileupload.FileUploadException; 
import org.apache.commons.fileupload.disk.DiskFileItemFactory; 
import org.apache.commons.fileupload.servlet.ServletFileUpload; 

public class CommonsFileUploadServlet extends HttpServlet { 

    private static final String TMP_DIR_PATH = "c:\\tmp"; 
    private File tmpDir; 
    private static final String DESTINATION_DIR_PATH = "c:\\tmp\\files"; 
    private File destinationDir; 

    public void init(ServletConfig config) throws ServletException { 
     super.init(config); 
     tmpDir = new File(TMP_DIR_PATH); 
     if (!tmpDir.isDirectory()) { 
      throw new ServletException(TMP_DIR_PATH + " is not a directory"); 
     } 
     //String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH); 
     destinationDir = new File(DESTINATION_DIR_PATH); 
     if (!destinationDir.isDirectory()) { 
      throw new ServletException(DESTINATION_DIR_PATH + " is not a directory"); 
     } 

    } 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     PrintWriter out = response.getWriter(); 
     response.setContentType("text/plain"); 
     out.println("<h1>Servlet File Upload Example using Commons File Upload</h1>"); 
     out.println(); 

     DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(); 
     /* 
     *Set the size threshold, above which content will be stored on disk. 
     */ 
     fileItemFactory.setSizeThreshold(1 * 1024 * 1024); //1 MB 
     /* 
     * Set the temporary directory to store the uploaded files of size above threshold. 
     */ 
     fileItemFactory.setRepository(tmpDir); 

     ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory); 
     try { 
      /* 
      * Parse the request 
      */ 
      List items = uploadHandler.parseRequest(request); 
      out.println("Count : " + items.size()); 
      Iterator itr = items.iterator(); 
      while (itr.hasNext()) { 
       FileItem item = (FileItem) itr.next(); 
       /* 
       * Handle Form Fields. 
       */ 
       if (item.isFormField()) { 
        out.println("Field = " + item.getFieldName() + ", Value = " + item.getString()); 
       } else { 
        //Handle Uploaded files. 
        out.println("Field Name = " + item.getFieldName() 
          + ", File Name = " + item.getName() 
          + ", Content type = " + item.getContentType() 
          + ", File Size = " + item.getSize()); 
        /* 
        * Write file to the ultimate location. 
        */ 
        File file = new File(destinationDir, item.getName()); 
        item.write(file); 
       } 
      } 
      out.close(); 
     } catch (FileUploadException ex) { 
      log("Error encountered while parsing the request", ex); 
     } catch (Exception ex) { 
      log("Error encountered while uploading file", ex); 
     } 

    } 
} 
相關問題