目的:一份代码运行三处, ios,android,web 。通信底层也共用。react-web使用的http请求是 JSONP,他的特点是: 只能发 get 请求,并且服务端要配合将请求回来的 callback 字段带回来。
客户端实现方案:
将 post 请求内容 base64 放到 url 里面
var fetch = Platform.OS === 'web'? require('ReactJsonp'): require('ReactFetch'); post(url,body) { let fetchOptions = { method: 'POST',deadline: kDeadline,timeout: kDeadline,headers: { 'Accept': 'application/json','Content-Type': 'application/json','uutype': AppGlobal.uutype,'latitude': AppGlobal.latitude,'longitude': AppGlobal.longitude,'token': AppGlobal.userToken,},body: JSON.stringify(body) } console.log('请求包头是=='+JSON.stringify(fetchOptions)); if (Platform.OS === 'web') { // Check if the user set their own params,and if not add a ? to start a list of params url += url.indexOf('?') === -1 ? '?' : '&'; //把参数放置到 url 里面 var optString = JSON.stringify(fetchOptions); var options = new Buffer(optString).toString("base64"); url += 'options='+options; } return fetch(url,fetchOptions) .then(res=>{ try { console.log('post method res = ' + JSON.stringify(res)); return res.json(); } catch (e) { return parseError; } },(res)=> { console.log(`request rejected ${res}`); throw res; }) }
1.支持JSONP
public static void renderJsonporJson(HttpServletResponse response,final String callbackName,final Object object,final String... headers){ if (callbackName!=null&&!callbackName.equals("")) { renderJsonp(response,callbackName,object,headers); }else { renderJson(response,headers); } }
2.支持POST内容放到URL里面的解码
流程是:修改 DispatchController 为自定义,然后在自定义类里面改写 httpservletrequest ,解码 url 里面的 post 内容,然后把内容填写到新的 request 的 head 和 body 里面去。
public class CustomDispatch extends DispatcherServlet { @Autowired protected void doDispatch(HttpServletRequest request,HttpServletResponse response) throws Exception { System.out.println("CustomDispatch --------- doDispatch "); String option = request.getParameter("options"); if(option != null){ //为JSONP请求特殊处理,修改 request 的内容(因为 jsonp 只能 get请求) // System.out.println("CustomDispatch --------- doDispatch options options"); HashMap m=new HashMap(request.getParameterMap()); //取出参数 base64解码 byte[] b = Encodes.decodeBase64(option); String jsonOption = new String(b); //替换 request HttpServletRequest req = (HttpServletRequest) request; HttpRequestChangeable wrapRequest=new HttpRequestChangeable(req,m,jsonOption); request=wrapRequest; //这是rquest就和本身的request一样了 }else{ } super.doDispatch(request,response); } }
package com.defa.tcm.common.customDispatch; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import javax.servlet.ServletRequest; public class HttpHelper { /** * 获取请求Body * * @param request * @return */ public static String getBodyString(ServletRequest request) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = request.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream,Charset.forName("UTF-8"))); String line = ""; while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return sb.toString(); } }
@SuppressWarnings("unchecked") public class HttpRequestChangeable extends HttpServletRequestWrapper { private Map params; private final byte[] body; private final HashMap headersHash; private final List headKey; public HttpRequestChangeable(HttpServletRequest request,Map newParams,String postContent) { super(request); this.params = newParams; JSONObject jsonObj = JSONObject.fromObject(postContent); String bodyStr = jsonObj.getString("body"); String headers = jsonObj.getString("headers"); JSONObject jsonHead = JSONObject.fromObject(headers); headersHash = new HashMap(); parserToMap(headers,headersHash ); //打印 head // Enumeration e = request.getHeaderNames() ; // while(e.hasMoreElements()){ // String name = (String) e.nextElement(); // String value = request.getHeader(name); // System.out.println(name+" = "+value); // // } //设置 head key headKey = new ArrayList(); Iterator keys=jsonHead.keys(); while(keys.hasNext()){ String key=(String) keys.next(); if(key != "body"){ headKey.add(key); } } //设置 head 和 body body = bodyStr.getBytes(Charset.forName("UTF-8")); // body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8")); } public Map getParameterMap() { return params; } public Enumeration getParameterNames() { Vector l = new Vector(params.keySet()); return l.elements(); } public String[] getParameterValues(String name) { Object v = params.get(name); if (v == null) { return null; } else if (v instanceof String[]) { return (String[]) v; } else if (v instanceof String) { return new String[] { (String) v }; } else { return new String[] { v.toString() }; } } public String getParameter(String name) { Object v = params.get(name); if (v == null) { return null; } else if (v instanceof String[]) { String[] strArr = (String[]) v; if (strArr.length > 0) { return strArr[0]; } else { return null; } } else if (v instanceof String) { return (String) v; } else { return v.toString(); } } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public boolean isFinished() { if(bais.available() == 0){ return true; } return false; } @Override public boolean isReady() { if(bais.available() > 0){ return true; } return false; } @Override public void setReadListener(ReadListener readListener) { // TODO Auto-generated method stub } }; } @Override public String getHeader(String name) { return (String) headersHash.get(name); // return super.getHeader(name); } @Override public Enumeration<String> getHeaderNames() { return new Enumeration(){ int count = headKey.size(); int curIndex = 0; @Override public boolean hasMoreElements() { if(curIndex < count){ return true; } return false; } @Override public Object nextElement() { if(curIndex < count){ Object res = headKey.get(curIndex++); return res; } return null; } }; // return super.getHeaderNames(); } @Override public Enumeration<String> getHeaders(final String name) { return new Enumeration(){ int count = 1; int curIndex = 0; @Override public boolean hasMoreElements() { if(curIndex < count){ return true; } return false; } @Override public Object nextElement() { if(curIndex < count){ curIndex++; return headersHash.get(name); } return null; } }; // return super.getHeaders(name); } // public static Map parserToMap(String s,Map initMap){ Map map= initMap; if(map == null){ map = new HashMap(); } JSONObject json=JSONObject.fromObject(s); Iterator keys=json.keys(); while(keys.hasNext()){ String key=(String) keys.next(); String value=json.get(key).toString(); if(value.startsWith("{")&&value.endsWith("}")){ map.put(key,parserToMap(value,null)); }else{ map.put(key,value); } } return map; } public static final byte[] readBytes(InputStream is,int contentLen) { if (contentLen > 0) { int readLen = 0; int readLengthThisTime = 0; byte[] message = new byte[contentLen]; try { while (readLen != contentLen) { readLengthThisTime = is.read(message,readLen,contentLen - readLen); if (readLengthThisTime == -1) {// Should not happen. break; } readLen += readLengthThisTime; } return message; } catch (IOException e) { // Ignore // e.printStackTrace(); } } return new byte[] {}; } }