質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

2回答

17616閲覧

spring+thimeleaf+tomcatでPOST送信が文字化け

Satoshi_Okada

総合スコア19

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

1グッド

2クリップ

投稿2016/03/10 06:55

Spring boot + thimeleaf + tomcatでWEBアプリ開発を行っております。

<使用ミドルウェア>
spring boot:1.3.2
thimeleaf

<開発マシン>
jdk:1.8.0.74
マシン:Windows7
IDE:eclipse4.4
ビルドツール:Gradle
tomcat:8.0.32

上記開発マシンにおいて、gradleタスクでwarファイルを作成し、
開発マシン上のTomcatにデプロイして動作確認を行ったところ、
HTML画面からPOST送信された画面入力値が、メソッドにおいて文字化けしていました。

各部分の記述は以下の通りです。

・HTML
<meta charset="UTF-8">

・Spring
AbstractAnnotationConfigDispatcherServletInitializerを継承したクラスで、
下記のように記述。

@Override protected Filter[] getServletFilters() { CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setEncoding("UTF-8"); characterEncodingFilter.setForceEncoding(true); return new Filter[] { characterEncodingFilter }; }

・Tomcxat
Server.xmlに下記のように記述

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

web.xmlにcharacterEncodingFilter を追加すれば治るよ、という情報があちこちにあったため、
追加してみたのですがそれでもだめでした……、

FindBugなどでPOSTの中身を見てみると、

/search?_csrf=d473774b-719c-4903-8f57-f4975138f755&baseCdC=&clntDnoC=&clntSeqC=&loginDateFrom=&loginDateTo=&nmKaV=%EF%BD%B1%EF%BD%B1%EF%BD%B1&nmKjV=%E3%81%82%E3%81%82%E3%81%82&ofcdC=&shcdC=&telNo=&zpcdC=

のようにUTF-8で送信されているように見えるので、
サーバー内部で文字コードが変換されているように思えます。

また、Javaで取得した文字コードをチェックしたところ、
ISO-8859_1になってしまっているようで、文字コード変換をかけてUTF8にすれば正しい値が取得できました。

とりとめもなく記載してしまいましたが、
上記のような現象に何か心当たりなどあるかたがおられましたら、
ご教授いただきたく思います。

inoy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

過去にSpringBootを利用したときに、同じように POST したデータが文字化けするという事象があり
もしかしたら同じ状況かもしれません

その際の状況で分かったのは、
SpringSecurityFilterChain の方が CharacterEncodingFilter より先に実行される場合があり、
CharacterEncodingFilter で指定した文字コードが有効にならないというのが原因でした

以下の WebSecurityConfig を追加して、強制的に SpringSecurityFilterChain より先に CharacterEncodingFilter を実行するように設定することで解決できましたよ

java

1@Configuration 2@EnableWebSecurity 3public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 4 @Override 5 protected void configure(HttpSecurity http) throws Exception { 6 CharacterEncodingFilter filter = new CharacterEncodingFilter(); 7 filter.setEncoding("UTF-8"); 8 filter.setForceEncoding(true); 9 http.addFilterBefore(filter, CsrfFilter.class); 10 } 11}

これは環境依存な問題のようで、
文字化けしない環境では CharacterEncodingFilter の方が先に実行されるんですが、
サーバーによって SpringSecurityFilterChain が先に実行される場合があり、その時に文字化けしているようでした
実行の順番はデバッグログに出てきます

その先は時間がなく調査はしてないので根本原因は分かっていませんが。。

(参考)
http://stackoverflow.com/questions/20863489/characterencodingfilter-dont-work-together-with-spring-security-3-2-0

投稿2016/03/16 01:38

編集2016/03/16 01:47
Chanmoro

総合スコア97

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Satoshi_Okada

2016/03/16 03:58 編集

回答有り難うございます。 対応してみたのですが、また化けてしまいました。 >サーバーによって SpringSecurityFilterChain が先に実行される場合があり、その時に文字化けしているようでした 実行の順番はデバッグログに出てきます そこで、上記のログを確認してみたところ、 Tomcat環境の場合、 ``` 16-03-16 12:49:57 INFO org.springframework.boot.context.embedded.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*] 16-03-16 12:49:57 INFO org.springframework.boot.context.embedded.DelegatingFilterProxyRegistrationBean - Filter springSecurityFilterChain was not registered (possibly already registered?) ``` のように出ていました。 ローカル環境だと ``` 16-03-16 12:56:52 INFO org.springframework.boot.context.embedded.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*] 16-03-16 12:56:52 INFO org.springframework.boot.context.embedded.DelegatingFilterProxyRegistrationBean - Mapping filter: 'springSecurityFilterChain' to: [/*] ``` のようにでているため、この辺りも関係してそうな気がします。 Spring Security Filterの設定とかが悪いのかな……。 その辺りを改めて確認してみます。
Satoshi_Okada

2016/03/16 05:59

コメントしたエラーは 、SpringSecurityFilterの順序を一番目にしたために発生した事象でした。 どこかのサイトで、SpringSecurityは一番目にしないとだめだよ! って書いてあったのを読んでそうしていたのですが……。まさかこんなところで問題が起きるとは……。 >SpringSecurityFilterChain の方が CharacterEncodingFilter より先に実行される場合があり、 CharacterEncodingFilter で指定した文字コードが有効にならないというのが原因でした この情報から問題に気づくことができ、対応することができました。 ありがとうございました。
Chanmoro

2016/03/16 06:07

解決してよかったです! 一番最初に setEncoding された文字コードが有効になって後からは上書きできないという仕様があるようで、 恐らく SpringSecurityFilterChain 内のどこかのフィルターがデータ内容のチェックのために文字コードを先にセットしてしまっているのが原因になっているんだと考えてます
guest

0

Local環境では問題なかったということでしょうか?

私は以下のような設定で問題なかったのですが…
参考になれたらいいなと思います。

すでに解決されたかもしれませんが…笑

java

1@Configuration 2public class ThymeleafConfig { 3 4 @Bean 5 public ServletContextTemplateResolver templateResolver() { 6 ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(); 7 resolver.setPrefix("/templates/"); 8 resolver.setSuffix(".html"); 9 resolver.setTemplateMode("HTML5"); 10 resolver.setOrder(1); 11 resolver.setCharacterEncoding("UTF-8"); 12 13 //Test 14 //resolver.setCacheable(false); 15 16 return resolver; 17 } 18 19 /** 20 * ThymeleafのDialect 21 * IEのHack対応、コメントの中にもThymeleaf使えるようにする。 22 * <!--[if IE]> 23 * <![endif]--> 24 * 25 * @return 26 */ 27 @Bean 28 public ConditionalCommentsDialect conditionalCommentDialect() { 29 return new ConditionalCommentsDialect(); 30 } 31 32}

java

1 2import java.io.File; 3import java.io.IOException; 4import java.nio.charset.Charset; 5import java.util.List; 6 7import javax.servlet.Filter; 8import javax.servlet.FilterChain; 9import javax.servlet.FilterConfig; 10import javax.servlet.MultipartConfigElement; 11import javax.servlet.ServletException; 12import javax.servlet.ServletRequest; 13import javax.servlet.ServletResponse; 14import javax.servlet.http.HttpServletRequest; 15 16import org.apache.catalina.Context; 17import org.apache.catalina.session.StandardManager; 18import org.apache.catalina.startup.Tomcat; 19import org.springframework.beans.factory.annotation.Autowired; 20import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; 21import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; 22import org.springframework.boot.context.embedded.FilterRegistrationBean; 23import org.springframework.boot.context.embedded.MultipartConfigFactory; 24import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer; 25import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer; 26import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; 27import org.springframework.context.annotation.Bean; 28import org.springframework.context.annotation.ComponentScan; 29import org.springframework.context.annotation.Configuration; 30import org.springframework.context.annotation.Import; 31import org.springframework.context.annotation.PropertySource; 32import org.springframework.context.support.ResourceBundleMessageSource; 33import org.springframework.core.env.Environment; 34import org.springframework.data.domain.PageRequest; 35import org.springframework.data.web.PageableHandlerMethodArgumentResolver; 36import org.springframework.http.converter.HttpMessageConverter; 37import org.springframework.http.converter.StringHttpMessageConverter; 38import org.springframework.remoting.rmi.RmiProxyFactoryBean; 39import org.springframework.validation.Validator; 40import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 41import org.springframework.web.method.support.HandlerMethodArgumentResolver; 42import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; 43import org.springframework.web.servlet.config.annotation.EnableWebMvc; 44import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 45import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 46import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 47 48/** 49 * MVCの全体を設定する 50 * @author park 51 */ 52@EnableWebMvc 53@ComponentScan(basePackages = {"xxx"}) 54@Import({JpaConfiguration.class, JavaMailConfiguration.class}) 55@PropertySource({ "classpath:config.properties" }) 56@Configuration 57public class WebMvcConfig extends WebMvcConfigurerAdapter { 58 59 @Autowired 60 private Environment env; 61 62 // ********************************************************************** 63 // URLとVIEWページのマッピング設定 64 // ********************************************************************** 65 @Override 66 public void addViewControllers(ViewControllerRegistry registry) { 67 registry.addViewController("/common/category.html").setViewName("common/category"); 68 } 69 70 // ********************************************************************** 71 // ページング処理のDefault値設定 72 // ********************************************************************** 73 @Override 74 public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 75 PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver(); 76 resolver.setFallbackPageable(new PageRequest(0, 20)); // Default page 77 // list 20 78 resolver.setPageParameterName("page.page"); 79 resolver.setSizeParameterName("page.size"); 80 argumentResolvers.add(resolver); 81 } 82 83 // ********************************************************************** 84 // リソースのURLと実際の経路のマッチングやキャッシュなどを指定 85 // APサーバの指定で実際はWEBサーバ側で処理を行うこと 86 // ********************************************************************** 87 @Override 88 public void addResourceHandlers(ResourceHandlerRegistry registry) { 89 90 registry.addResourceHandler("/css/**").addResourceLocations("classpath:/static/css/").setCachePeriod(31556926); 91 registry.addResourceHandler("/font-awesome/**").addResourceLocations("classpath:/static/font-awesome/").setCachePeriod(31556926); 92 registry.addResourceHandler("/fonts/**").addResourceLocations("classpath:/static/fonts/").setCachePeriod(31556926); 93 registry.addResourceHandler("/js/**").addResourceLocations("classpath:/static/js/").setCachePeriod(31556926); 94 registry.addResourceHandler("/img/**").addResourceLocations("classpath:/static/img/").setCachePeriod(31556926); 95 registry.addResourceHandler("/pdf/**").addResourceLocations("classpath:/static/pdf/").setCachePeriod(31556926); 96 97 //set Upload Path 98 registry.addResourceHandler("/uploads/**").addResourceLocations("file:" + env.getProperty("upload.path") + File.separatorChar); 99 100 } 101 102 @Override 103 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 104 configurer.enable(); 105 } 106 107 108 // ********************************************************************** 109 // 国際化関連設定 110 // ********************************************************************** 111 // Provides internationalization of messages 112 @Bean 113 public ResourceBundleMessageSource messageSource() { 114 ResourceBundleMessageSource source = new ResourceBundleMessageSource(); 115 source.setBasename("messages"); 116 return source; 117 } 118 119 //Validatorのメッセージ 120 @Override 121 public Validator getValidator() { 122 123 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); 124 validator.setValidationMessageSource(messageSource()); 125 return validator; 126 } 127 128 // ********************************************************************** 129 // Exception Handler追加 130 // 予期してないエラーが発生した場合 131 // ********************************************************************** 132 @Bean 133 public GlobalException handlerExceptionResolver() { 134 GlobalException handler = new GlobalException(); 135 return handler; 136 } 137 138 139 // ********************************************************************** 140 // エンコード設定 141 // ********************************************************************** 142 // JSON(@RestController、@ResponseBody)時の文字化け対応 143 @Override 144 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 145 converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8"))); 146 } 147 148 // リクエストパラメタのエンコードを設定する 149 @Bean 150 public FilterRegistrationBean getFilterRegistrationBean() { 151 FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); 152 filterRegistrationBean.setFilter(new CharacterEncodingFilter()); 153 return filterRegistrationBean; 154 } 155 156 private static class CharacterEncodingFilter implements Filter { 157 protected String encoding; 158 public void init(FilterConfig filterConfig) throws ServletException { 159 encoding = "UTF-8"; 160 } 161 public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 162 HttpServletRequest request = (HttpServletRequest) servletRequest; 163 request.setCharacterEncoding(encoding); 164 filterChain.doFilter(servletRequest, servletResponse); 165 } 166 public void destroy() { encoding = null; } 167 } 168 169 170 @Bean 171 public TomcatEmbeddedServletContainerFactory tomcatFactory() { 172 return new TomcatEmbeddedServletContainerFactory() { 173 @Override 174 protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer( 175 Tomcat tomcat) { 176 tomcat.enableNaming(); 177 return super.getTomcatEmbeddedServletContainer(tomcat); 178 } 179 }; 180 } 181 182 @Bean 183 public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer() { 184 return new EmbeddedServletContainerCustomizer() { 185 @Override 186 public void customize(ConfigurableEmbeddedServletContainer container) { 187 if (container instanceof TomcatEmbeddedServletContainerFactory) { 188 TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory = (TomcatEmbeddedServletContainerFactory) container; 189 tomcatEmbeddedServletContainerFactory 190 .addContextCustomizers(new TomcatContextCustomizer() { 191 @Override 192 public void customize(Context context) { 193 194 /** 195 * 196 */ 197 198 StandardManager m = new StandardManager(); 199 m.setPathname(env.getProperty("session.persistence.path")); 200 context.setManager(m); 201 202 } 203 }); 204 } 205 } 206 }; 207 } 208 209 210 // ********************************************************************** 211 // ファイルアップロードダウンロード関連設定 212 // ********************************************************************** 213 @Bean 214 MultipartConfigElement multipartConfigElement() { 215 MultipartConfigFactory factory = new MultipartConfigFactory(); 216 factory.setMaxFileSize("5MB"); 217 factory.setMaxRequestSize("5MB"); 218 return factory.createMultipartConfig(); 219 } 220 221 222} 223

投稿2016/03/11 05:32

kongbab04

総合スコア53

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Satoshi_Okada

2016/03/14 10:44

>Local環境では問題なかったということでしょうか?  はい。その通りです。 >私は以下のような設定で問題なかったのですが…  参考になれたらいいなと思います。  提示頂いたソースを参考に色々やってみたのですが未だに解決せず……。  何が悪いのか全くわからない状況です;
kongbab04

2016/03/15 02:12

そうなんですね… 私はいつもjarで回してまして… お役に立てずすみません… CharacterEncodingFilterを指定すればできるという記事はいくつかいましたが… https://github.com/spring-projects/spring-boot/issues/1182 ちなみに gradleのcompile時のエンコード設定です… def defaultEncoding = 'UTF-8' [compileJava, compileTestJava]*.options*.encoding = defaultEncoding
kongbab04

2016/03/15 02:21

もし、 web.xml使われてるのであれば <filter> <filter-name>charcterEncodingFilter</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>charcterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> とかで対応できるみたいですね… http://javatechnology.net/spring/webbrowser-japanese-characters/
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問