Текст UTF-8 искажается, когда форма отправляется как multipart/form-data
Я загружаю файл на сервер. Форма HTML для загрузки файла имеет 2 поля:
- Имя файла - текстовое поле HTML, в котором пользователь может указать имя на любом языке.
- Загрузка файла - HTMl 'файл', где пользователь может указать файл с диска для загрузки.
Когда форма отправляется, содержимое файла принимается должным образом. Однако, когда имя файла (пункт 1 выше) считывается, оно искажается. Символы ASCII отображаются правильно. Когда имя дается на каком-то другом языке (немецкий, французский и т.д.), Возникают проблемы.
В методе сервлета кодировка символов запроса установлена в UTF-8. Я даже попытался сделать фильтр, как было сказано - Как я могу сделать этот код для отправки текстового поля формы UTF-8 с помощью Работа jQuery/Ajax? - но, похоже, это не работает. Кажется, что только имя файла искажено.
Таблица MySQL, в которой находится имя файла, поддерживает UTF-8. Я дал случайные неанглийские символы, и они были сохранены/отображены правильно.
Используя Fiddler, я отслеживал запрос и все данные POST передавались правильно. Я пытаюсь определить, как/где данные могут искажаться. Любая помощь будет принята с благодарностью.
Ответы
Ответ 1
У меня была такая же проблема при использовании 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);
Ответ 2
Просто используйте библиотеку загрузки сообщества Apache.
Добавьте URIEncoding="UTF-8"
к коннектору Tomcat и используйте FileItem.getString( "UTF-8" ) вместо FileItem.getString() без указанной кодировки.
Надеюсь на эту помощь.
Ответ 3
Я застрял в этой проблеме и обнаружил, что это был вызов вызова
request.setCharacterEncoding("UTF-8");
что вызывало проблему. Он должен быть вызван перед любым вызовом request.getParameter(), поэтому я сделал специальный фильтр для использования в верхней части моей цепочки фильтров.
http://www.ninthavenue.com.au/servletrequest-setcharactercoding-ignored
Ответ 4
У меня была та же проблема, и оказалось, что помимо указания кодировки в Filter
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().
Ответ 5
Если кто-то натолкнулся на эту проблему при работе с веб-приложением 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'
}
Ответ 6
Я использую 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
Ответ 7
Фильтр является ключевым для 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
Ответ 8
Я использую Primefaces со стекловолокном и SQL Server.
В моем случае я создал Webfilter во внутреннем интерфейсе, чтобы получить каждый запрос и преобразовать его в 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) мне нужно установить форму пареметра enctype в UTF-8, например @Kevin Rahe:
<h:form id="frmt" enctype="multipart/form-data;charset=UTF-8" >
<!-- your code here -->
</h:form>
Ответ 9
Объект фильтра и настройка Tomcat для поддержки URI UTF-8 важны только в том случае, если вы передаете строку запроса URL-адреса, как в случае с GET HTTP. Если вы используете POST с строкой запроса в теле сообщения HTTP, важно, чтобы это был тип содержимого запроса, и это зависит от браузера, чтобы установить тип содержимого в UTF-8 и отправьте контент с этой кодировкой.
Единственный способ сделать это - сообщить браузеру, что вы можете принимать только UTF-8, устанавливая заголовок Accept-Charset при каждом ответе на "UTF-8; q = 1, ISO-8859-1; q = 0,6". Это поставит UTF-8 как лучшее качество и набор символов по умолчанию, ISO-8859-1, как приемлемый, но более низкого качества.
Когда вы говорите, что имя файла искажено, оно искажено в возвращаемом значении HttpServletRequest.getParameter?
Ответ 10
У меня такая же проблема. Единственное решение, которое работало для меня, это добавление <property = "defaultEncoding" value = "UTF-8"> в multipartResoler в файле конфигурации Spring.
Ответ 11
Вы также должны убедиться, что ваш фильтр кодирования (org.springframework.web.filter.CharacterEncodingFilter) в вашем файле web.xml сопоставлен перед многочастным фильтром (org.springframework.web.multipart.support.MultipartFilter).
Ответ 12
Я думаю, что я опаздываю на вечеринку, но когда вы используете wildfly, вы можете добавить кодировку по умолчанию в standalone.xml. Просто найдите в standalone.xml для
<servlet-container name="default">
и добавьте кодировку следующим образом:
<servlet-container name="default" default-encoding="UTF-8">
Ответ 13
Чтобы избежать преобразования всех параметров запроса вручную в 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 в контроллере, где он определен.
Ответ 14
Вы не используете UTF-8 для кодирования текстовых данных для HTML-форм. В стандарте html определяются два кодировки, а соответствующая часть этого стандарта находится здесь. "Старая" кодировка, чем обрабатывает ascii, - application/x-www-form-urlencoded. Новый, который работает правильно, является multipart/form-data.
В частности, объявление формы выглядит следующим образом:
<FORM action="http://server.com/cgi/handle"
enctype="multipart/form-data"
method="post">
<P>
What is your name? <INPUT type="text" name="submit-name"><BR>
What files are you sending? <INPUT type="file" name="files"><BR>
<INPUT type="submit" value="Send"> <INPUT type="reset">
</FORM>
И я думаю, что все, о чем вам нужно беспокоиться - веб-сервер должен справиться с этим. Если вы пишете что-то, что напрямую читает InputStream из веб-клиента, вам нужно будет прочитать RFC 2045 и RFC 2046.