20

Ajax で UTF-8 文字列を含むフォームを送信する際に問題があります。Tomcatサーバーで実行されるStruts Web アプリケーションを開発しています。これは、UTF-8 で動作するようにセットアップした環境です。

  • Tomcat のファイルのタグに属性URIEncoding="UTF-8" useBodyEncodingForURI="true"を追加しました。Connectorconf/server.xml

  • 私はutf-8_general_ciデータベースを持っています

  • 次のフィルタを使用して、リクエストとレスポンスが UTF-8 でエンコードされていることを確認しています

    package filters;
    
    import java.io.IOException;
    import javax.servlet.*;
    
    public class UTF8Filter implements Filter {
        public void destroy() {}
    
        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);
        }
    
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    }
    
  • このフィルターを WEB-INF/web.xml で使用します

  • JSON 応答に次のコードを使用しています。

    public static void populateWithJSON(HttpServletResponse response,JSONObject json)
    {
       String CONTENT_TYPE="text/x-json;charset=UTF-8";
       response.setContentType(CONTENT_TYPE);
       response.setHeader("Cache-Control", "no-cache");
       try {
            response.getWriter().write(json.toString());
       } catch (IOException e) {
        throw new ApplicationException("Application Exception raised in RetrievedStories", e);
       }
    }
    

すべて正常に動作しているようです (データベースからのコンテンツは適切に表示され、データベースに UTF-8 で保存されているフォームを送信できます)。問題は、 Ajax でフォームを送信できないことです。私は jQuery を使用していますが、問題は Ajax リクエストに contentType フィールドがないことだと思いました。しかし、私は間違っていました。IDと本文を含むコメントを送信するための非常に単純なフォームがあります。body フィールドは、スペイン語、ドイツ語など、さまざまな言語にすることができます。

を含む body textarea でフォームを送信するとcontraseñaFirebugに次のように表示されます。

リクエスト ヘッダー

  • ホスト localhost:8080
  • Accept-Charset ISO-8859-1、utf-8;q=0.7;*q=0.7
  • Content-Type application/x-www-form-urlencoded; 文字セット UTF-8

Firebugでパラメーターを指定して Copy Locationを実行すると、エンコーディングが既に間違っているように見えます。

http://localhost:8080/Cerepedia/corporate/postStoryComment.do?&body=contrase%C3%B1a&id=88

これは私のjQueryコードです:

function addComment() {
    var comment_body = $("#postCommentForm textarea").val();
    var item_id = $("#postCommentForm input:hidden").val();
    var url = rooturl+"corporate/postStoryComment.do?";
    $.post(url, { id:  item_id, body: comment_body } ,
        function(data){
        /* Do stuff with the answer */
    }, "json");  }

jQuery を使用してフォームを送信すると、サーバー側で次のエラーが発生します (私はHibernateを使用していることに注意してください)。

javax.servlet.ServletException: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    at org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:520)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:427)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.security.AuthorizationFilter.doFilter(AuthorizationFilter.java:78)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.hibernate.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:30)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at filters.UTF8Filter.doFilter(UTF8Filter.java:14)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at com.cerebra.cerepedia.item.dao.ItemDAOHibernate.addComment(ItemDAOHibernate.java:505)
    at com.cerebra.cerepedia.item.ItemManagerPOJOImpl.addComment(ItemManagerPOJOImpl.java:164)
    at com.cerebra.cerepedia.struts.item.ItemAction.addComment(ItemAction.java:126)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
    at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
    at org.apache.struts.actions.MappingDispatchAction.execute(MappingDispatchAction.java:166)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
    ... 26 more
Caused by: java.sql.BatchUpdateException: Incorrect string value: '\xF1a' for column 'body' at row 1
    at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:657)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
    ... 44 more
26-ago-2008 19:54:48 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() para servlet action lanzó excepción
java.sql.BatchUpdateException: Incorrect string value: '\xF1a' for column 'body' at row 1
    at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:657)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at com.cerebra.cerepedia.item.dao.ItemDAOHibernate.addComment(ItemDAOHibernate.java:505)
    at com.cerebra.cerepedia.item.ItemManagerPOJOImpl.addComment(ItemManagerPOJOImpl.java:164)
    at com.cerebra.cerepedia.struts.item.ItemAction.addComment(ItemAction.java:126)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
    at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
    at org.apache.struts.actions.MappingDispatchAction.execute(MappingDispatchAction.java:166)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.security.AuthorizationFilter.doFilter(AuthorizationFilter.java:78)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.hibernate.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:30)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at filters.UTF8Filter.doFilter(UTF8Filter.java:14)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)
javax.servlet.ServletException: java.lang.NumberFormatException: null
    at org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:520)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:427)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.security.AuthorizationFilter.doFilter(AuthorizationFilter.java:78)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.hibernate.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:30)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at filters.UTF8Filter.doFilter(UTF8Filter.java:14)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NumberFormatException: null
    at java.lang.Long.parseLong(Unknown Source)
    at java.lang.Long.valueOf(Unknown Source)
    at com.cerebra.cerepedia.struts.item.ItemAction.addComment(ItemAction.java:120)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
    at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
    at org.apache.struts.actions.MappingDispatchAction.execute(MappingDispatchAction.java:166)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
    ... 26 more
26-ago-2008 20:13:25 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() para servlet action lanzó excepción
java.lang.NumberFormatException: null
    at java.lang.Long.parseLong(Unknown Source)
    at java.lang.Long.valueOf(Unknown Source)
    at com.cerebra.cerepedia.struts.item.ItemAction.addComment(ItemAction.java:120)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
    at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
    at org.apache.struts.actions.MappingDispatchAction.execute(MappingDispatchAction.java:166)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.security.AuthorizationFilter.doFilter(AuthorizationFilter.java:78)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.cerebra.cerepedia.hibernate.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:30)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at filters.UTF8Filter.doFilter(UTF8Filter.java:14)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)
4

6 に答える 6

13

呼び出しの前に次を追加しようとしましたか:

$.ajaxSetup({ 
    scriptCharset: "utf-8" , 
    contentType: "application/json; charset=utf-8"
});

オプションについては、こちらで説明しています。

contentType : サーバーにデータを送信するときは、この content-type を使用します。デフォルトは「application/x-www-form-urlencoded」で、ほとんどの場合これで問題ありません。

scriptCharset : 'jsonp' または 'script' dataType と GET タイプのリクエストのみ。リクエストが特定の文字セットとして解釈されるように強制します。リモート コンテンツとローカル コンテンツの文字セットが異なる場合にのみ必要です。

于 2008-08-27T08:49:48.917 に答える
3

私は同じ問題を抱えています。Internet Explorer 8 が次のヘッダーを送信するのを見ました。

content-type = application/x-www-form-urlencoded

Firefoxはこれを送信します:

content-type = application/x-www-form-urlencoded; charset=UTF-8

私の解決策は、jQuery で Firefox コンテンツ タイプを使用するように強制することでした。

$.ajaxSetup({ scriptCharset: "utf-8" ,contentType: "application/x-www-form-urlencoded; charset=UTF-8" });
于 2010-01-12T12:35:56.387 に答える
1

同じ問題があり、mysql-connector-odbc-3.51.16 にダウングレードして修正しました。

于 2008-11-27T11:29:55.277 に答える
1

私も同じ問題を抱えていたので、次のように修正しました。

PHP では、データをデータベースに格納する前に、htmlentities()関数を使用しました。そして、データを表示している間、html_entity_decode()関数を使用しました。これはうまくいきました。これがあなたにとってもうまくいくことを強く願っています。

于 2009-04-09T03:52:52.383 に答える
0

例外は jdbc エラーであるため、入力をデータベースに送信する前にキャプチャすることをお勧めします。

java.sql.BatchUpdateException: 不正な文字列値: 行 1 の列 'body' の '\xF1a'

単一の文字が例外を引き起こしています。

一部の文字を手動でオーバーライドする必要がある場合があります。ラテン文字以外の言語を扱う場合 (私もそうです)、これがよくある苦痛であることがわかります。

于 2010-09-07T07:23:01.907 に答える
0

私はこの問題をよく見かけます。メタは、PHP データ操作で常に機能するとは限らないため、最初に次のように入力してください。

<?php header('Content-type: text/html; charset=utf-8');  ?>
于 2010-06-28T01:02:39.803 に答える