2015-02-06 69 views
0

我使用PlayFramework 2.3構建了一個應用程序,並且在某處我上傳了一個CSV文件並用它填充了一個數據庫。僅在產品上編碼問題?

當訪問本地應用程序(127.0.0.1:9000)並進行上傳時,一切正常,文件上傳,解析並添加到數據庫中沒有任何問題。

同樣的過程在生產中完成,但所有重音字符被替換爲��

dev和督促之間的主要區別在於:

  • 在DEV,我從PlayFramework(的LocalServer)直接訪問該應用
  • 在PROD,我訪問通過NGINX應用程式,即redirets到Play(代理)的本地實例。

這裏的的相關詳細信息:

  • CSV文件是UTF-8編碼(注:當然,這是我測試相同的文件)
  • 到數據庫的連接使用由UTF-8 - >db.default.url="jdbc:mysql://127.0.0.1/2leadin?characterEncoding=UTF-8"
  • 我測試(使用Firefox),在HTML頁面中UTF-8

最後回來了,這是我的Nginx的配置:

proxy_buffering off; 
proxy_set_header X-Real-IP $remote_addr; 
proxy_set_header X-Scheme "https"; 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
proxy_set_header Host $http_host; 
proxy_http_version 1.1; 

server { 
     listen 80; 
     server_name my.2lead.in; 
     return  301 https://my.2lead.in; 
} 

server { 
    listen    443; 
    ssl     on; 
    root     /var/www/2lead.in/errors/; 

    # http://www.selfsignedcertificate.com/ is useful for development testing 
    ssl_certificate  /ssl/2lead.crt; 
    ssl_certificate_key /ssl/2lead.key; 

    # From https://bettercrypto.org/static/applied-crypto-hardening.pdf 
    ssl_prefer_server_ciphers on; 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive 
    ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA'; 
    add_header Strict-Transport-Security max-age=15768000; # six months 
    # use this only if all subdomains support HTTPS! 
    # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" 

    keepalive_timeout 70; 
    server_name my.2lead.in; 

    # remove the robots line if you want to use wordpress' virtual robots.txt 
    location = /robots.txt { access_log off; log_not_found off; } 
    location = /favicon.ico { access_log off; log_not_found off; } 

    location /public { 
     alias /var/www/2lead.in/my/public/; 
     access_log off; 
     log_not_found off; 
    } 

    location/{ 
     proxy_pass http://127.0.0.1:9100; 
    } 

    location ~ /\.git { 
     deny all; 
    } 

    error_page 502 @maintenance; 
    location @maintenance { 
     rewrite ^(.*)$ /error502.html break; 
    } 
} 

我失蹤了,你有什麼想法,爲什麼我只有在PROD編碼問題?我很確定這是因爲NGinx,但我找不到原因。

謝謝。

+0

推測你的應用程序假設它的一個文件操作是默認的字符集,並且生產服務器和本地機器的默認值不同(檢查'file.encoding' env var;它取決於語言環境。)有一個可能會省略顯式字符集並最終導致這些可移植性問題的地方數量,但沒有看到您的代碼就很難知道。如果是NGinx,我會很驚訝。 – Mikesname 2015-02-07 19:28:15

+0

我用'System.out.println(System.getProperty(「file.encoding」));'做了一個簡單的HelloWorld.java。在本地服務器上,我有'UTF-8'輸出,在prod中,我有'ANSI_X3.4-1968'。我嘗試用'java -DFile.encoding = UTF-8 HelloWorld'強制編碼,結果相同(ANSI_X3.4-1968)。爲什麼?怎麼樣? :/ – 2015-02-09 09:57:47

+0

等一下,這是一個糟糕的命令行,用'java -Dfile。encoding = UTF-8 HelloWorld「(較低的F /文件),輸出爲UTF-8。我會重新啓動應用程序,看看這是否解決了這個問題。 – 2015-02-09 09:59:46

回答

1

默認的Java字符集取決於語言環境,取自file.encoding環境變量(請參閱this answer)。這可能會導致不同機器的行爲差異,就像你看到的一樣。有兩種方法來解決,權宜方式和更強大和可移植的方式:

  • 確保服務器與-Dfile.encoding=UTF-8運行(或任何你的開發環境匹配)
  • 確保您所有的文件操作指定字符集,明確如this answer所述

總之,依靠默認的系統編碼是脆弱的,在大多數情況下應該避免。