1. 程式人生 > >HttpPost 傳輸Json資料並解析

HttpPost 傳輸Json資料並解析

這裡寫個測試用例模擬外部呼叫,通過httppost 傳遞一個json封裝的表單資料。

包:import com.alibaba.fastjson.JSON;
       import com.alibaba.fastjson.JSONArray;

相關總結:http://xp9802.iteye.com/blog/2123450

每個json包都不一樣,這裡主要是fastjson包的用法。

測試1:用StringEntity 封裝的json字串傳遞一個類。
@Test
public void synYxGoodsInfoTest() {
try {
String url = "http://10.118.44.14:8070/teshi-web/goods/synYxGoods";
GoodsInfo goodsInfo = new GoodsInfo();
goodsInfo.setGoods_id(111);
goodsInfo.setGoodsName("1231213");
goodsInfo.setBrand(1);
goodsInfo.setType(1);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
String jsonstr = JSON.toJSONString(goodsInfo);
StringEntity se = new StringEntity(jsonstr);
                        se.setContentType("text/json");
                       se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                       httpPost.setEntity(se);
                       HttpResponse response=httpClient.execute(httpPost);
//輸出呼叫結果
if(response != null && response.getStatusLine().getStatusCode() == 200) {
String result=EntityUtils.toString(response.getEntity());
 
// 生成 JSON 物件
JSONObject obj = JSONObject.parseObject(result);

String errorcode = obj.getString("errorcode");

if("000".equals(errorcode)) {
System.out.println("addHkfishOrder_request_success");
}
}
 
} catch (Exception e) {
System.out.println("======回不來了=======" );
}



    控制層接收資料
@RequestMapping(value = "/synYxGoods")
@ResponseBody
public String synYxGoods(HttpServletResponse response,HttpServletRequest request) throws IOException {
//String json = request.getParameter("param");  
//這是通過通過get方式去url 拼接的鍵值對,post方式取不到值。
request.setCharacterEncoding("UTF-8");        //返回頁面防止出現中文亂碼

BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));//post方式傳遞讀取字元流
String jsonStr = null;
StringBuilder result = new StringBuilder();
try {
while ((jsonStr = reader.readLine()) != null) {
result.append(jsonStr);
}
} catch (IOException e) {
e.printStackTrace();
}
reader.close();// 關閉輸入流

JSONObject jsonObject = JSONObject.parseObject(result.toString()); // 取一個json轉換為物件
logger.info(jsonObject);
GoodsInfo goodsInfo = new GoodsInfo();
Date date = new Date();
goodsInfo.setAccess_code1("001");
                goodsInfo.setAccess_code1("001");
                goodsInfo.setGoodsName(jsonObject.getString("goodsName"));     //通過鍵取到值,再將值封裝到類裡面。
               goodsInfo.setType(Integer.parseInt(jsonObject.getString("type")));
List<ResultData<String>> data = yxGoodsService.synYxGoodsInfo(goodsInfo);
String json_str = JSON.toJSONString(data);
return write(response, json_str);
}



接收到的字串:result.toString():{"brand":1,"goodsName":"1231213","goods_id":111,"type":1}

JSONObject jsonObject = JSONObject.parseObject(result.toString());  用pareseObject 直接轉換為object類

這種方式對對方只傳遞一個類封裝的json字串,最實用。

測試2:用StringEntity 封裝的json字串傳遞一個list。

在輸入端構造一個List,用list 新增幾個物件,再轉換為json 傳過去,接收到的資料與測試1 的差距就是多了一個"[ ]"

goodsInfoList.add(goodsInfo1);

goodsInfoList.add(goodsInfo2);

goodsInfoList.add(goodsInfo3);

String jsonstr = JSON.toJSONString(list);

 接收到的字串:result.toString():[{"brand":1,"goodsName":"1231213","goods_id":111,"type":1},{"brand":1,"goodsName":"1231213","goods_id":111,"type":1}]

List<GoodsInfo> list = JSON.parseArray(result.toString(), GoodsInfo.class);//可轉換為list的物件。

測試3:用StringEntity 封裝的json字串傳遞一個由list封裝的類中。

public class GoodsInfoRet {
private List<GoodsInfo> goodList;
private int total_record;
public List<GoodsInfo> getGoodList() {
return goodList;
}
public void setGoodList(List<GoodsInfo> goodList) {
this.goodList = goodList;
}
public int getTotal_record() {
return total_record;
}
public void setTotal_record(int total_record) {
this.total_record = total_record;
}
}

GoodsInfoRet good_dto = new GoodsInfoRet();
good_dto.setGoodList(goodsInfoList);
good_dto.setTotal_record(goodsInfoList.size());

JSONObject jsonObject = JSONObject.parseObject(result.toString()); 

接收到的字串:result.toString(): {"goodList":[{"brand":1,"goodsName":"1231213","goods_id":111,"type":1},{"brand":1,"goodsName":"1231213","goods_id":111,"type":1}],"total_record":2}

                                jsonObject:       {"goodList":[{"brand":1,"goodsName":"1231213","goods_id":111,"type":1},            {"brand":1,"goodsName":"1231213","goods_id":111,"type":1}],"total_record":2}

在轉換為list物件: Object jsonArray = jsonObject.get("goodList");  
                      List<GoodsInfo> list = JSON.parseArray(jsonArray+"", GoodsInfo.class);
 //後面一定要跟上+,因為轉換的是字串才行

得到一個list的類,然後再遍歷,在迴圈。

綜上,用StringEntity se = new StringEntity(jsonstr); 是很有用的,能輸出正確的程式碼格式,最後方便解析。

測試4:用List<NameValuePair>  封裝的json字串傳遞一個由list封裝的類中。

String jsonstr = JSON.toJSONString(goodsInfo);

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("param",jsonstr));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response=new DefaultHttpClient().execute(httpPost);

接收到的字串:result.toString() : param=%7B%22brand%22%3A1%2C%22goodsName%22%3A%221231213%22%2C%22goods_id%22%3A111%2C%22type%22%3A1%7D

這是url 編碼,所以需要轉碼

URLDecoder.decode(result.toString(), "utf-8")

param={"brand":1,"goodsName":"1231213","goods_id":111,"type":1}

這時需要對字串進行一個split的處理。

String s = URLDecoder.decode(result.toString(), "utf-8");

String[] s1 = s.split("=");

JSONObject object = JSON.parseObject(s1[1]);  

這樣就能得到一個已object 的物件

自行封裝

goodsInfo.setGoodsName(jsonObject.getString("goodsName"));

測試5:用List<NameValuePair>  封裝的json字串傳遞一個由list封裝的list中。

                    String jsonstr = JSON.toJSONString(goodsInfoList);

                 轉換的是一個list物件轉換為json字串,再放在 params 中,

那麼接收到的字串是:

URLDecoder.decode(result.toString(), "utf-8")

param=[{"brand":1,"goodsName":"1231213","goods_id":111,"type":1}]

這時需要對字串進行一個split的處理。

String s = URLDecoder.decode(result.toString(), "utf-8");

String[] s1 = s.split("=");

List<GoodsInfo> list  = JSONObject.parseArray(s1[1],GoodsInfo.class);

這樣就能得到一個已list的物件。

綜上:傳list封裝的json要比類封裝的json方便,用StringEntity要比List<NameValuePair> 要方便,前者不用再轉碼和切割字串。

其他:httpge方式傳遞資料

如果用url拼接字串傳遞資料,那會非常方便,前端不用做任何處理,使用與PHP與java之間的互動。php只用拼接url就行了。

如:前端url

http://10.118.44.37:8070/teshi-web/supplier/synYxSupplier?supplierName=pl_test3%28%%29&supplierNo=60074&stName=%E4%81&stId=6

後端java 接收

@RequestMapping(value="/totallist")
public String totallist(OrderQuery orderQuery, HttpServletResponse response) {
if(StringUtils.isEmpty(orderQuery.getOrder())) {
orderQuery.setOrder("desc");
}
return query(orderQuery, response);
//return "order/totallist";
}

只需要和介面人確認相關欄位的鍵值,然後用Spring自動封裝,不用request 拿值,這樣取得傳過來的一個類是非常方便的是非常方便的。

但是不適用與傳list物件。