символы нолатин в выводе xml - PullRequest
2 голосов
/ 01 ноября 2009

Edit: я жестко закодировал charcter и использую repsonse writer, чтобы написать его, он все еще получается Knigsberger

response.setCharacterEncoding("UTF-8");

            response.setContentType(contentType);
            //if(contentType!=null)response.setHeader("Content-Type",contentType);
            Writer writer = response.getWriter();//new OutputStreamWriter(response.getOutputStream(),"UTF-8");
            System.err.println("character encoding is "+response.getCharacterEncoding());


            writer.write("Königsberger ");
            writer.flush();

Edit: Я пробовал setContentType и setContentEncoding до вызова getWriter (), все равно нет разницы в выводе:

        if(res.length()>0){
            //pw.write(res);
            response.setCharacterEncoding("UTF-8");
            response.setContentType(contentType);
            //if(contentType!=null)response.setHeader("Content-Type",contentType);
            Writer writer = response.getWriter();//new OutputStreamWriter(response.getOutputStream(),"UTF-8");
            System.err.println("character encoding is "+response.getCharacterEncoding());


            writer.write(res);
            writer.flush();
        }

Я читаю некоторые немецкие символы, а затем выводю их в формате XML из сервлета Java, вот как я читаю их в UTF8:

int len=0;
        byte[]buffer=new byte[1024];
        OutputStream os = sock.getOutputStream();
        InputStream is = sock.getInputStream();
        query += "\r\n";
        os.write(query.getBytes("UTF8"));//iso8859_1"));

            do{
                len = is.read(buffer);
             if (len>0) { 
                 if(outstring==null)outstring=new StringBuffer();
                 outstring.append(new String(buffer,0,len, "UTF8"));
             }
           }while(len>0);
System.out.println(outstring);

System.out выводит строку правильно: Königsberger

Однако, когда я повторяю эту строку из моего servletResponse также используя charset = UTF-8 оно сожрано: Кенигсбергер

private void outputResponse(String res, HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        String outputFormat = getOutputFormat(request);
        String contentType=null;
        PrintWriter pw = response.getWriter();
        //response.setCharacterEncoding("UTF-8");
        System.err.println("output "+res);

        contentType= "text/xml; charset=UTF-8";
        res="<?xml version=\"1.0\" encoding=\"utf-8\"?>" + res;

        if(contentType!=null)response.setHeader("Content-Type",contentType);
        if(res.length()>0){
            pw.write(res);
        }
        pw.flush();

    }

Ответы [ 4 ]

3 голосов
/ 01 ноября 2009
do{
  len = is.read(buffer);
  if (len>0) { 
    if(outstring==null) outstring=new StringBuffer();
    outstring.append(new String(buffer,0,len, "UTF8"));
  }
}while(len>0);

Это не очень хороший способ декодирования UTF-8, поскольку символы могут быть повреждены на границах буфера ( подробности здесь ). UTF-8 - это кодировка с переменной шириной , поэтому для хранения символов требуется от одного до четырех байтов. Если это работает, вам просто везет. Лучше кодировать и декодировать, используя классы Reader / Writer ( подробности здесь ).

Полагаю, вам нужно вызвать setContentType или setCharacterEncoding до вызова getWriter. Я не думаю, что достаточно позвонить setHeader напрямую.


Этот код сервлета будет правильно кодировать и передавать строку образца в виде данных UTF-8:

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/xml; charset=UTF-8");
    PrintWriter pw = response.getWriter();
    pw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    pw.write("<data>K\u00F6nigsberger</data>");
    pw.flush();
    pw.close();
  }

Обратите внимание, что я использую escape-последовательность \u00F6 для вывода символа U + 00F6 ( & # x00F6; ), чтобы не повредить символ в моем текстовом редакторе или во время компиляции процесс ( см. подробнее ).

Возможно ли, что данные неправильно интерпретируются на клиенте? Проверьте вывод с помощью шестнадцатеричного редактора.

Кодированный как UTF-8, "K\u00F6nigsberger" должен стать байтовой последовательностью:

4b c3 b6 6e 69 67 73 62 65 72 67 65 72

... где символ U + 00F6 ( & # x00F6; ) становится c3 b6. Вы можете использовать такой код, чтобы проверить свои значения:

  public static void main(String[] args) throws IOException {
    String konigsberger = "K\u00F6nigsberger";
    dumpHex(System.out, konigsberger.getBytes("UTF-8"));
  }

  private static void dumpHex(PrintStream out, byte[] data) {
    for (byte b : data) {
      out.format("%02x ", b);
    }
    out.println();
  }
1 голос
/ 22 июня 2012

Вы должны следовать примеру и заставить сервлет response понять, какой кодировке следовать:

response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
ServletOutputStream out =response.getOutputStream();
out.write(output.getBytes("UTF-8"));    
0 голосов
/ 04 марта 2015

Я тоже сталкивался с такой же проблемой. Я только что сделал следующие вещи, и это работает нормально:

byte[] k =xml.getBytes(UTF8_CHARSET); // xml is the string with unicode content.  getBytes("UTF-16") encodes given String into a sequence of bytes and returns an array of bytes. you can use xml.getBytes(UTF-16); for utf-16 encoding

response.setContentType("text/xml");
response.setContentLength(k.length);
response.getOutputStream().write(k);
response.getOutputStream().flush();
response.getOutputStream().close();
0 голосов
/ 02 ноября 2009

Вы всегда можете использовать такие объекты, как это:

<test>
&#228;
&#252;
&#229;
</test>

чтобы получить:

<test>
ä
ü
å
</test>

Может быть, не совсем то, что вы хотите, но хороший обходной путь. Вы можете использовать такие сайты, как utf8-chartable.de , чтобы найти нужное значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...