Spring CharacterEncodingFilterを適用して単一の問題を解決


問題を迅速に解決したい場合は、次のコードをwebに置いてください.xmlに貼り付けます.
<filter>
	<filter-name>encodingFilter</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>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
前回EC 2が攻撃された後、サーバに入って異常な兆候があるかどうかを確認するのに慣れていることが多い.同時に自然にサービスを利用してみましたが、今回は意外な問題を発見しました.
コメントを書く時だけハングルが割れてしまう…!

伝言板やニックネームの変更など他の入力ラベルにはハングルが入力されていますが、他のところは普通で、コメントに問題があっただけです.

ログを見ると、コントローラからパラメータに値を渡すと、ハングルが破壊された状態で渡されることがわかります.

フロントではよく過ごしていますか?


まずフロントからサーバに移行する際,正しい遷移があるかどうかを確認するためにフォームのsubmit機能をブロックし,内部内容を確認した.
// jquery
let regReviewForm = $("#reg_review_form");
alert(regReviewForm.serialize());
jQuery上の.serialze()は、フォーム内のデータをクエリータイプとして簡単に作成できます.submit機能をブロックし、上のコードを実行し、スキップされたデータを表示します.

key値がcontentの部分を調べたところ,ハングル符号化の形式であることが分かった.
let regReviewContent = document.getElementById('review_content').value;
alert(regReviewContent);
jqueryを使用しない項目であれば、上記の方法でtextareaの値を取得して確認することもできます.

textareaの値もハングルの正しい入力を正常に確認できます.
これにより、フロントでハングルを入力し、サーバーに送信しても問題がないことを確認できます.

サーバーで受け取りましたか?


他に問題はなかったのでJSP内部の問題か、コメント内容を入力したtextareaが問題だと思っていたのですが、問題ではないことを確認しました.
しかし、ハングルは他の形式やtextareaとは全く違いがなく、グーグルを使っても原因を見つけるのは難しい.このとき,フィルタを用いた正確な解決策が見つかった.
<filter>
	<filter-name>encodingFilter</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>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
org.springframework.web.filter.CharacterEncodingFilterで符号化パラメータをUTF-8、forceEncodingパラメータをtrueに設定し、すべてのパスに対応するフィルタを適用します.
異なる点は、Dispatcherサーブレットがコントローラ間で要求をブロックする場合、フィルタは、クライアントの要求がDispatcherサーブレットに到達する前に要求をブロックすることである.
インタフェースおよびフィルタに関する内容は、ここにおいてさらに確認することができる.
上記のコードに示すように、web.xmlにフィルタを登録すると、設定したパスに従ってフィルタが操作されます.

CharacterEncodingFilterはどのように操作されていますか?


CharacterEncodingFilterはSpringが提供するフィルタクラスで、OncePerRequest Filterを拡張しています.
OncePerRequest Filterは、フィルタを繰り返し実行する問題を回避し、doFilter内部メソッドを実行するために一度だけ実行されるフィルタです.
次はCharacterEncodingFilterクラスで、Webを表示します.これはxml設定に適した部分のみをインポートしたコードです.
public class CharacterEncodingFilter extends OncePerRequestFilter {
    @Nullable
    private String encoding;
    private boolean forceRequestEncoding;
    private boolean forceResponseEncoding;

  ...
  ...

    public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
        this(encoding, forceEncoding, forceEncoding);
    }

    public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
        Assert.hasLength(encoding, "Encoding must not be empty");
        this.encoding = encoding;
        this.forceRequestEncoding = forceRequestEncoding;
        this.forceResponseEncoding = forceResponseEncoding;
    }

  ...
  ...
  
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String encoding = this.getEncoding();
        if (encoding != null) {
            if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                request.setCharacterEncoding(encoding);
            }

            if (this.isForceResponseEncoding()) {
                response.setCharacterEncoding(encoding);
            }
        }

        filterChain.doFilter(request, response);
    }
}
Init-paramを使用して符号化とforceEncodeが定義されているため、2つのパラメータのコンストラクション関数が呼び出され、3つのパラメータを持つコンストラクション関数が再び呼び出され、次のフィールドが定義されます.
  • encoding : "UTF-8"
  • forceRequestEncoding : true
  • forceResponseEncoding : true
  • doFilterInternalメソッドの内部結果はrequestです.setCharacterEncoding(「UTF-8」)を実現しました.
    すなわち、すべての要求が要求される.setCharacterEncoding(「UTF-8」)の役割はこれと同じといえる.

    CharacterEncodingFilterの適用後




    コントローラでハングルが正常に受信され、サービス画面でも処理が完了したことを確認できます.
    リファレンス
  • https://homesi.tistory.com/entry/Springを選択します。
  • https://mangkyu.tistory.com/173
  • https://pgnt.tistory.com/102