react-web 的 JSONP 模拟 POST 请求

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










评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值