目的:一份代码运行三处, 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, object, 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[] {};
}
}