你們在估作功能測試的時候,不知有沒有發現,若是統一用utf-8做爲編碼,POST測試請求中若是帶有漢字就會亂碼。java
{"box":[{"entityId":7,"id":7,"idea":"?????","jPAContext":{"insideTransaction":true,"jPAConfig":{"configName":"play","enabled":true,"insideTransaction":true,"jPAContext":{"$ref":".."},"jpql":{}}},"persistent":false,"type":1},{"entityId":8,"id":8,"idea":"???","jPAContext":{"$ref":"$.box[0].jPAContext"},"persistent":false,"type":5},{"idea":"???","jPAContext":{"$ref":"$.box[0].jPAContext"},"persistent":false,"type":3}],"code":"jack","entityId":1003,"id":1003,"ip":"192.168.1.122","jPAContext":{"$ref":"$.box[0].jPAContext"},"nick":"??","passwd":"jack2","persistent":true,"qqmail":"200@qq.com"}
這個是一個典型的編碼問題,可是我找遍play也沒有找到相關的設置,只好用調試看看。 cookie
1.我在從yml文件讀取數據過程,我發現數據還不是亂碼 框架
2.在請求到達第七章說起的ActionInvoker中的時候,已經亂碼。 ide
因此我推測,應該是play框架對POST請求進行封裝是出了問題在全部功能測試父類FunctionalTest中,重載了許多POST方法,其中根本是這個POST: play.test.FunctionalTest.java測試
public static Response POST(Request request, Object url, Map parameters, Map files) { List parts = new ArrayList(); for (String key : parameters.keySet()) { parts.add(new StringPart(key, parameters.get(key))); } for (String key : files.keySet()) { Part filePart; try { filePart = new FilePart(key, files.get(key)); } catch (FileNotFoundException e) { throw new RuntimeException(e); } parts.add(filePart); } MultipartRequestEntity requestEntity = new MultipartRequestEntity(parts.toArray(new Part[]{}), null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { requestEntity.writeRequest(baos); } catch (IOException e) { throw new RuntimeException(e); } InputStream body = new ByteArrayInputStream(baos.toByteArray()); String contentType = requestEntity.getContentType(); Http.Header header = new Http.Header(); header.name = "content-type"; header.values = Arrays.asList(new String[]{contentType}); request.headers.put("content-type", header); return POST(request, url, MULTIPART_FORM_DATA, body); }
在這個方法中,有一個new StringPart()的方法this
parts.add(new StringPart(key, parameters.get(key)));
我跟進去以後,發現這廝也是重載方法: com.ning.http.multipart.StringPart.java編碼
public StringPart(String name, String value, String charset) { super(name, "text/plain", charset != null ? charset : "US-ASCII", "8bit"); if(value == null) throw new IllegalArgumentException("Value may not be null"); if(value.indexOf('\0') != -1) { throw new IllegalArgumentException("NULs may not be present in string parts"); } else { this.value = value; return; } } public StringPart(String name, String value) { this(name, value, null); }
代碼一目瞭然,url
super(name, "text/plain", charset != null ? charset : "US-ASCII", "8bit");
若是沒有charset,他就會默認「US-ASCII」! 問題出來的,解決方法就多了,能夠在StringPart處將默認的改成「UTF-8」,也能夠在POST方法中多傳一個「UTF-8」參數。 可是,這兩個方法都不太優雅,我這裏提供一種方法。首先構造一個測試類的父類: function.BasisTest.javaidea
public class BasisTest extends FunctionalTest{ public static Response POST(Object url, Map parameters) { return POST(newLocalRequest(), url, parameters, new HashMap()); } public static Request newLocalRequest() { Request request = Request.createRequest( null, "GET", "/", "", null, null, null, null, false, 80, "localhost", false, null, null ); request.encoding = "utf-8"; return request; } }
覆蓋FunctionalTest的POST類,並構建本身的Request,這個地方還能夠設定cookie,方便在有登錄攔截的狀況下,進行功能測試。這裏主要是設定請求的encoding。 而後在FunctionalTest中POST方法中將StringPart構造方法該爲三個參數,加上request.encoding。調試
parts.add(new StringPart(key, parameters.get(key), request.encoding));
這樣編碼就是活的,能夠自行設定。
{"box":[{"entityId":7,"id":7,"idea":"老馬太瘦了","jPAContext":{"insideTransaction":true,"jPAConfig":{"configName":"play","enabled":true,"insideTransaction":true,"jPAContext":{"$ref":".."},"jpql":{}}},"persistent":false,"type":1},{"entityId":8,"id":8,"idea":"矮矬富","jPAContext":{"$ref":"$.box[0].jPAContext"},"persistent":false,"type":5},{"idea":"汝甚吊","jPAContext":{"$ref":"$.box[0].jPAContext"},"persistent":false,"type":3}],"code":"jack","entityId":1003,"id":1003,"ip":"192.168.1.122","jPAContext":{"$ref":"$.box[0].jPAContext"},"nick":"老馬","passwd":"jack2","persistent":true,"qqmail":"200@qq.com"}