package com.dongantech.eshop.http.request.functionaltest;import junit.framework.TestCase;public class TestGetMethodRequestHandler extends TestCase{
private GetMethodRequestHandler handler = null;
private Request request = null;
public void setUp(){
request = new Request();
request.setSchema("http");
request.setHost("192.168.1.101");
request.setMethod("GET");
request.setPort(8080);
request.setAppName("dabusiness");
request.setResourcePath("product/searcher");
request.setParameter("request","search");
try {
request.setParameter("qs",URLEncoder.encode("hrchyLevel = 1 and name like '%主板%'","utf-8"));//此处对查询串qs进行编码一次
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
request.setContentEncoding("utf-8");
request.setResponseBuilder("product.searcher");

handler = new GetMethodRequestHandler();
}
public void testHandleRequest() throws HandleRequestException{
Response response = handler.handle(request);
assertEquals("notification",response.getType());
List<Product> products = (List<Product>) response.getContext().get("products");
assertTrue(products.size() == 3);
}
}
package com.dongantech.eshop.http.request;public class GetMethodRequestHandler implements RequestHandler{
public Response handle(Request theReq) throws HandleRequestException {
try{
Response response = sendRequest(theReq);
return response;
}catch(UnsupportedEncodingException uee){
throw new HandleRequestException("按编码("+theReq.getContentEncoding()+")把请求参数内容进行编码时出现异常!",uee);
} catch (MalformedURLException mue) {
throw new HandleRequestException("构建URL对象出现了异常!",mue);
}catch(IOException ioe){
throw new HandleRequestException("打开连接时出现了异常!",ioe);
}
}
protected Response sendRequest(Request theReq) throws IOException{
String urlString = theReq.getUrlString();//此方法的内部逻辑对查询串qs进行了第二次编码
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
connection.setRequestProperty("content-encoding",theReq.getContentEncoding());
InputStream is = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(is);
String responseType = getResponseTypeFrom(connection);
MapResponseBuilder mapResponseBuilder = MapResponseBuilderFactory.getInstance().getMapResponseBuilder(responseType);
mapResponseBuilder.setInputStreamReader(reader);
ResponseBuilder responseBuilder = ResponseBuilderFactory.getInstance().getResposeBuilder(theReq.getResponseBuilder());
responseBuilder.setMapResponseBuilder(mapResponseBuilder);
return responseBuilder.build();
}
private String getResponseTypeFrom(URLConnection theConnection){
String contentType = theConnection.getHeaderField("Content-Type");
if(contentType != null){
if(contentType.startsWith(Response.CONTENTTYPE_JSON)){
return "json" ;
}
}
return null;
}
}
而Servlet的内部逻辑有方法把参数进行解码。
protected Map<String,String> decodeParameters(Map<String,String[]> theParameterMap,String theCharsetEncoding) throws UnsupportedEncodingException{
Map<String,String> decodedParams = new HashMap<String,String>();
Set<Map.Entry<String,String[]>> entrySet = theParameterMap.entrySet();
String name = null;String value = null;
for(Map.Entry<String,String[]> e : entrySet){
name = e.getKey();
value = e.getValue()[0];
value = URLDecoder.decode(value, theCharsetEncoding);
decodedParams.put(name, value);//此处是进行的第二次解码,第一次解码好像是由Servlet容器(或者说Tomcat服务器)给解了
}
return decodedParams;
}
而Servlet容器或Tomcat服务器不是按我预期的utf-8编码来进行解码的,因为最开始我的功能测试TestGetMethodRequestHandler是不能通过的,最开始我的查询串qs只进行了一次编码时,根据调试得知Servlet内部会抛出异常,由于中文乱码。我看到URLConnection有一方法setRequestProperty设置请求属性,弱弱的问一下,那一个属性是指示容器来按请求的指定编码来解码参数的。功能测试使用了maven的插件tomcat-maven-plugin的目标tomcat:run来启动tomcat服务器还想问一下,每一个服务器都会自动把请求参数进行一次解码吗?这样我就需要在功能测试当中把请求参数进行二次编码了