Русские символы в форме Spring MVC
Всем привет! (РЕШЕНИЕ ЕСТЬ)
Я понимаю, эта не первой свежести тема....
Столкнулся в Spring MVC с проблемой Encoding, "utf8"
Чтобы решить эту проблему я пересмотрел много ответов, что я делал:
- В конфигурации Spring MVC добавил фильтр public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {......
@Override
protected Filter[] getServletFilters() {
Filter[] filters;
CharacterEncodingFilter encFilter;
HiddenHttpMethodFilter httpMethodFilter = new HiddenHttpMethodFilter();
encFilter = new CharacterEncodingFilter();
encFilter.setEncoding("UTF-8");
encFilter.setForceEncoding(true);
filters = new Filter[] {httpMethodFilter, encFilter};
return filters;
}
- В конфигурации Spring Security добавил фильтр public class WebSecurityConfig extends WebSecurityConfigurerAdapter {...
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.addFilterBefore(new EncodingFilter(), BasicAuthenticationFilter.class);
http
.authorizeRequests()
......
Сам фильтр:
public class EncodingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
chain.doFilter(request, response);
}
}
- Я использую Thymeleaf, в классе настроек представления я добавил нужную информацию
@Bean
public SpringResourceTemplateResolver springTemplateResolver(){
SpringResourceTemplateResolver springTemplateResolver = new SpringResourceTemplateResolver();
springTemplateResolver.setCharacterEncoding("UTF-8");
...
@Bean
public ViewResolver viewResolver(){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(springTemplateEngine());
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setContentType("text/html; charset=UTF-8");
...
- В конфигурации источника данных я также указал
а. свойства строки подключения:
try {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/mysqlo?" +
"useJDBCCompliantTimezoneShift=true" +
"&useLegacyDatetimeCode=false" +
"&serverTimezone=UTC" +
"&useSSL=false" +
"&useUnicode=true" +
"&connectionCollation=utf8_general_ci" +
"&characterSetResults=utf8" +
"&characterEncoding=utf-8");
Пробовал **useUnicode=true&characterEncoding=UTF-8"** - не помогло
b. Свойства hibernate
@Bean
public Properties hibernateProperties() {
Properties hibernateProp = new Properties();
....
//Кодировка
hibernateProp.put("hibernate.connection.characterEncoding", "utf8");
hibernateProp.put("hibernate.connection.CharSet", "utf8");
hibernateProp.put("hibernate.connection.useUnicode", true);
- Сделал настройку Томкат в файле server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
- Настройку Maven сделал
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
...
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<source>8</source>
...
- Теги кодировки на страницах html добавил
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
- В настройках самой базы стоят следующие параметры
В свойствах таблиц настройки следующие
- Сами файлы html я проверил в формате UTF-8 сохранены. Дополнения: 9.1 Файлы классов тоже в формате UTF-8
- Кодировку в IDEJ, проверил UTF-8
- Кодировка при отправке браузером также проверена
- При отадке уточнил, запрос в контроллер попадает уже никакой
- Сам контроллер:
@RequestMapping(value = "/vend.new", method = RequestMethod.POST)
public String newVendor (@ModelAttribute("newvend") @Valid Vendor vend, BindingResult bindingResult, Model model){
if (bindingResult.hasErrors()) {
return "ok";
}
sv.getInsertVokmar(vend);
return "ok";
}
При тестировании проекта я обнаружил, фильтры при инициализации, создаются, регистрируются:
При получении запроса в контроллере фильтры куда-то пропадают:
Версии банок:
<failOnMissingWebXml>false</failOnMissingWebXml>
<jakartaee>8.0</jakartaee>
<spring.version>5.2.3.RELEASE</spring.version>
<jstl.version>1.2.1</jstl.version>
<tld.version>1.1.2</tld.version>
<servlets.version>3.1.0</servlets.version>
<jsp.version>2.3.1</jsp.version>
<hibernate.version>5.4.10.Finall</hibernate.version>
<kotlin.version>1.0.0</kotlin.version>
Очень, прошу подсказать, где ошибка и что я делаю не так.
Ответы (2 шт):
<%@ page language="java" pageEncoding="UTF-8"%> вот это в jsp, и в web.xml
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Решение для моего случая:
- Я обратил внимание что регистрация фильтров, которые отвечают за правильный вывод символов (Русские) при использовании Spring Security должна производится в конфигурации Spring Security, скорее всего это определенная особенность, которую ещё предстоит выяснить мне (если кто знает, прошу поделится опытом)
- Я удалил всю регистрацию фильтров из класса (пункт 1 моего вопроса):
public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {......
@Override
protected Filter[] getServletFilters() {
.....
- Я изменил фильтр в классе регистрации безопасности public class WebSecurityConfig extends WebSecurityConfigurerAdapter {... (пункт 2 моего вопроса)
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.addFilterBefore(new EncodingFilter(), ChannelProcessingFilter.class);
....
public class EncodingFilterConfig implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
chain.doFilter(request, response);
}
После данных изменений все работает. Вопрос остался в понимании сути этой строки http.addFilterBefore(new EncodingFilter(), ChannelProcessingFilter.class); а точнее в классе ChannelProcessingFilter.class - я понял это стандартный класс из системы безопасности (список классов безопасности) и для регистрации моего класса фильтра мне нудно добавить мой фильтр перед этим (есть еще несколько методов http.addFilte...)






