Турецкие символы не отображаются должным образом в HTML

Я пытаюсь напечатать что-то на веб-странице HTML, используя код сервлета. Я использую кодировку UTF-8, но турецкие символы не отображаются должным образом на веб-странице.

Как я определяю кодировку UTF-8:

  String htmlStart =  "<html>\n" +
                    "<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
 <title>" + title + "</title>
</head>\n" +
                    "<body bgcolor = \"#f0f0f0\">\n" +
                       "<h1 align = \"center\">" + title + "</h1>\n" +
                       "<ul>\n" + "  <li><b>"+url + "</b>" +  "</ul>\n"; 

Как я печатаю слова в html:

 for (String token : parsed) {
                med+= "<p>" +  token + "</p>\n"; 
                System.out.println(token);
            }   

Что пишет в консоль Eclipse приведенный выше код:

Мугла Ситки Кочман Юниверситеси

Что я вижу в сгенерированном HTML:

Mu?la S?tk? Кочман Юниверситеси


person Savas Ozturk    schedule 16.03.2021    source источник
comment
Пробовали читать в браузере? Мне кажется, что ваша консоль не поддерживает символы Unicode. Запишите его в файл и прочитайте в браузере или редакторе (с поддержкой UTF-8). Не доверяйте консоли для отображения правильных символов   -  person Giacomo Catenazzi    schedule 16.03.2021
comment
Хорошо, кажется, вы используете консоль Eclipse. Я добавил тег Eclipse к вашему вопросу.   -  person Sabuncu    schedule 16.03.2021
comment
Я попробовал несколько браузеров, таких как Firefox, Chrome и Opera, ничего не изменилось. Я думаю, что проблема не в просмотре, мы должны сосредоточиться на том, как кодировать HTML в Java.   -  person Savas Ozturk    schedule 18.03.2021
comment
Поскольку ваша проблема связана с указанием кодировки в Java, я заменил ваш тег html на java.   -  person skomisa    schedule 19.03.2021


Ответы (2)


Вы уже указываете "charset=utf-8" для сгенерированного HTML, поэтому чтение/рендеринг данных не должно быть проблемой в браузере (как вы предлагаете).

Но пример кода вашей консоли неверен, поскольку в нем не указано, что следует использовать UTF-8. Поведением по умолчанию будет использование кодировки по умолчанию вашей платформы при создании данных, что, вероятно, не то, что вам нужно.

Самый простой способ исправить это в вашем примере кода — переназначить System.out на PrintStream, который использует UTF-8, вызвав setOut():

String text = "Muğla Sıtkı Koçman Üniversitesi";
System.out.println(text + " (default PrintStream)");         
System.setOut(new PrintStream(System.out, true, "UTF8"));
System.out.println(text + " (UTF-8 PrintStream)");  

Однако, если я запускаю этот код из командной строки Windows, я получаю такой беспорядок:

Mu?la S?tk? Koçman Üniversitesi (default PrintStream)

Muğla Sıtkı Koçman Üniversitesi (UTF-8 PrintStream)

Первая строка не работает (как и ваша), потому что данные записываются и читаются с использованием кодировки по умолчанию, которая на моей машине Cp437. И вторая строка не работает, потому что, хотя данные правильно записываются как UTF-8, они все еще отображаются с использованием Cp437.

Чтобы исправить это, явно установите кодовую страницу вашей консоли на UTF-8, указав chcp 65001 в консоли перед запуском вашего кода (по крайней мере, в Windows). Затем вы увидите, что вторая строка отображается правильно, потому что она и пишется, и читается как UTF-8:

Mu?la S?tk? Koman niversitesi (default PrintStream)

Muğla Sıtkı Koçman Üniversitesi (UTF-8 PrintStream)

Примечания:

  • Вы не показываете, как сгенерированный HTML создается в вашем сервлете, но если вы убедитесь, что он написан как UTF-8, все будет в порядке.
  • Если вы все еще застряли, обновите свой вопрос, чтобы показать полный источник вашего сервлета, и если он слишком велик, создайте минимальный, Воспроизводимый пример.
  • Я думаю, что бесполезно, что Eclipse делает что-то за кулисами, чтобы выходные данные правильно отображались в консоли. Я не уверен, почему команда Eclipse решила это сделать, потому что это маскирует основную проблему в вашем коде.
person skomisa    schedule 19.03.2021
comment
Хорошо, что Eclipse очень полезен. Не помогает в производстве. - person Sabuncu; 19.03.2021

Я благодарен за ваш ответ, который помог мне решить дело. Как и в большинстве моих задач по исправлению ошибок, усилия по созданию минимального воспроизводимого примера снова помогли. Я нашел виновника, после его удаления мой код работал так, как я хотел, хотя я до сих пор не знаю, как это влияет на кодировку UTF-8:

response.getWriter().append("Served at: ").append(request.getContextPath()); 

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

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;

import javax.print.attribute.standard.Severity;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
   
/**
 * Servlet implementation class MyServlet
 */
@WebServlet("/Minimal")
public class Minimal extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Minimal() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // TODO Auto-generated method stub
         
        System.setOut(new PrintStream(System.out, true, "UTF8"));
        
        
        // The culprit code part which effects UTF-8's proper working 
        //response.getWriter().append("Served at: ").append(request.getContextPath());
        
        response.setContentType("text/html; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
         
          String title = "GEMED Software Requirements";
          String docType =  "<!doctype html public \"-//w3c//dtd html 4.0 " +
             "transitional//tr\">\n";
             
          String url = request.getParameter("site11");  
         
          String htmlStart =  docType + "<html>\n" +
                    "<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>" + title + "</title></head>\n" +
                    "<body bgcolor = \"#f0f0f0\">\n" +
                       "<h1 align = \"center\">" + title + "</h1>\n" +
                       "<ul>\n" + "  <li><b>"+url + "</b>" +  "</ul>\n"; 
          
         String med2 = "Türkçe: Muğla Sıtkı Koçman Üniversitesi Rektörü Çalışmayan Öğrencilerden Şikayetçi......" ;
          String htmlEnd =  "</body>" +  "</html>";
    
          out.println( htmlStart + med2 +  htmlEnd); 
    
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
person Savas Ozturk    schedule 21.03.2021
comment
Несколько замечаний: [1] Вам не нужно вызывать System.setOut() в коде сервлета, поэтому удалите его. Это имело отношение только к коду консольного приложения в вашем вопросе. [2] Вам также не нужно звонить setCharacterEncoding(). Это излишне, так как вы уже позвонили setContentType(). См. API кодирования и сервлета: setContentType или setCharacterEncoding. [3] Ваша проблема заключалась в том, что вы звонили response.getWriter().... до setContentType(). Это должно работать, если оно размещено после вызова setContentType(). - person skomisa; 22.03.2021