java - 使用 HttpURLConnection 将 XML 数据从 HTTP Java 客户端发送到 servlet 时出现问题

标签 java servlets character-encoding

我有独立的 java 客户端使用 httpURLconnection 类将 xml 数据发送到 http 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);
        }
    }

}

请帮助我摆脱这个问题。

最佳答案

我认为你把事情想得太复杂了。我刚刚写了一些类似的东西,它可以获取任何文件并通过 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);   
}

关于java - 使用 HttpURLConnection 将 XML 数据从 HTTP Java 客户端发送到 servlet 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4315798/

相关文章:

c#-4.0 - C# - 从 .txt 文件读取俄语文本

Python 字符编码

java - 我想在 Java Eclipse 中使用 JDBC 对上一个查询的 ResultSet 执行另一个 SQL 查询

JavaEE - Web 应用程序和导航逻辑

java - 如何检查 servlet 中的 sessionId 是否有效 (java)

tomcat - 无法在服务器上运行应用程序

java - 无法使用@WebMvcTest Autowiring MockMvc

java - 使用java从URL中删除jsessionid的正则表达式

java - decode() 没有读取任何内容,但解码了一条消息

scala - Play Framework Ning WS API 编码问题与 HTML 页面