Текст UTF-8 искажается, когда форма публикуется как multipart / form-data - PullRequest
49 голосов
/ 13 февраля 2009

Я загружаю файл на сервер. HTML-форма для загрузки файла имеет 2 поля:

  1. Имя файла - текстовое поле HTML, в котором пользователь может дать имя на любом языке.
  2. Загрузка файла - файл HTMl, в котором пользователь может указать файл с диска для загрузки.

Когда форма отправлена, содержимое файла получено правильно. Однако когда имя файла (пункт 1 выше) читается, оно искажается. Символы ASCII отображаются правильно. Когда имя дается на каком-либо другом языке (немецком, французском и т. Д.), Возникают проблемы.

В методе сервлета кодировка символов запроса установлена ​​в UTF-8. Я даже попытался сделать фильтр, как упомянуто - Как я могу сделать этот код для отправки текстовой области формы UTF-8 с jQuery / Ajax? , Кажется, что искажено только имя файла.

Таблица MySQL, в которую входит имя файла, поддерживает UTF-8. Я дал случайные неанглийские символы, и они хранятся / отображаются правильно.

Используя Fiddler, я отслеживал запрос, и все данные POST передаются правильно. Я пытаюсь определить, как / где данные могут быть искажены. Любая помощь будет принята с благодарностью.

Ответы [ 14 ]

54 голосов
/ 14 февраля 2009

У меня была такая же проблема при использовании Apache commons-fileupload. Я не выяснил, что вызывает проблемы, особенно потому, что у меня есть кодировка UTF-8 в следующих местах: 1. HTML метатег 2. Форма атрибута accept-charset 3. Фильтр Tomcat на каждый запрос, который устанавливает кодировку "UTF-8"

-> Мое решение заключалось в особом преобразовании строк из ISO-8859-1 (или любой другой кодировки по умолчанию вашей платформы) в UTF-8:

new String (s.getBytes ("iso-8859-1"), "UTF-8");

надеюсь, что помогает

Редактировать: начиная с Java 8 вы также можете использовать следующее:

new String (s.getBytes (StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
26 голосов
/ 12 сентября 2011

Просто используйте библиотеку Apache commons upload. Добавьте URIEncoding="UTF-8" к соединителю Tomcat и используйте FileItem.getString («UTF-8») вместо FileItem.getString () без указания кодировки.

Надеюсь, эта помощь.

18 голосов
/ 02 апреля 2012

Я застрял с этой проблемой и обнаружил, что это был порядок вызова на

request.setCharacterEncoding("UTF-8");

это было причиной проблемы. Он должен вызываться перед любым вызовом метода request.getParameter (), поэтому я создал специальный фильтр для использования в верхней части цепочки фильтров.

http://www.ninthavenue.com.au/servletrequest-setcharactercoding-ignored

11 голосов
/ 11 октября 2009

У меня была такая же проблема, и оказалось, что помимо указания кодировки в фильтре

request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");

необходимо добавить «acceptcharset» в форму

<form method="post" enctype="multipart/form-data" acceptcharset="UTF-8" > 

и запустить JVM с

-Dfile.encoding=UTF-8

Метатег HTML не требуется, если вы отправляете его в заголовке HTTP с помощью response.setCharacterEncoding ().

7 голосов
/ 12 августа 2015

Если кто-то натолкнулся на эту проблему при работе с веб-приложением Grails (или исключительно Spring), вот пост, который мне помог:

http://forum.spring.io/forum/spring-projects/web/2491-solved-character-encoding-and-multipart-forms

Чтобы установить кодировку по умолчанию UTF-8 (вместо ISO-8859-1) для многочастных запросов, я добавил следующий код в resources.groovy (Spring DSL):

multipartResolver(ContentLengthAwareCommonsMultipartResolver) {
    defaultEncoding = 'UTF-8'
}
3 голосов
/ 26 августа 2016

Я использую org.apache.commons.fileupload.servlet.ServletFileUpload.ServletFileUpload(FileItemFactory) и определение кодировки при считывании значения параметра:

List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);

for (FileItem item : items) {
    String fieldName = item.getFieldName();

    if (item.isFormField()) {
        String fieldValue = item.getString("UTF-8"); // <-- HERE
2 голосов
/ 13 февраля 2009

Фильтр является ключевым для IE. Несколько других вещей, чтобы проверить;

Что такое кодировка страницы и набор символов? Оба должны быть UTF-8

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

Что такое набор символов в метатеге?

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

В строке подключения MySQL указано UTF-8? например,

jdbc:mysql://127.0.0.1/dbname?requireSSL=false&useUnicode=true&characterEncoding=UTF-8
1 голос
/ 05 ноября 2014

Я использую Primefaces с glassfish и SQL Server.

В моем случае я создал Web-фильтр в бэк-энде, чтобы получать каждый запрос и конвертировать в UTF-8, например:

package br.com.teste.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

@WebFilter(servletNames={"Faces Servlet"})
public class Filter implements javax.servlet.Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);      
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub      
    }

}

В представлении (.xhtml) мне нужно задать для формы параметра энктипа значение UTF-8, например @Kevin Rahe:

    <h:form id="frmt" enctype="multipart/form-data;charset=UTF-8" >
         <!-- your code here -->
    </h:form>  
0 голосов
/ 13 июня 2019

Чтобы не преобразовывать все параметры запроса вручную в UTF-8, вы можете определить метод, отмеченный @InitBinder в вашем контроллере:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(String.class, new CharacterEditor(true) {
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            String properText = new String(text.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            setValue(properText);
        }
    });
}

Выше будет автоматически преобразовывать все параметры запроса в UTF-8 в контроллере, где он определен.

0 голосов
/ 28 марта 2019

Я думаю, что опаздываю на вечеринку, но когда вы используете дикую бабочку, вы можете добавить кодировку по умолчанию в standalone.xml. Просто найдите в standalone.xml

<servlet-container name="default"> 

и добавьте кодировку следующим образом:

<servlet-container name="default" default-encoding="UTF-8">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...