最近在做一个小玩意,用的别人的api,在本地调试的还好,部署到服务器上的时候发现对api的请求都是禁止跨域,可惜的是也没有提供jsonp接口
所以自已写了一个简单的代理http(s)请求的Servlet,用这个Servlet来访问别人的服务器,同时把结果原样返回来。
为了让自己的服务器支持跨域可以设置 resp.setHeader("Access-Control-Allow-Origin", "*")
,或者提供对结果进行jsonp封装的选项
参数
-
url
要代理的url,不携带http(s)和?后面的内容
-
urlParm
原url?后面的参数,需要进行一处理
?keywords=尽头&page=1 => keywords:尽头;page:1
-
reqProperty
用于setRequestProperty,不常用,构造同urlParm
-
post
是否是post请求,默认false
-
https
是否是https请求,默认false
-
respText
是否返回文本,默认false,直接返回文件流
-
respContentType
当respText为true时候,返回的类型,默认为text/plain,出现异常是application/json,jsonp为true时候是application/x-javascript,特殊情况自定义,一般上面的就很标准了
-
charset
当respText为true时候可以设置返回文本的编码,默认是utf-8
-
jsonp
是否返回jsonp,默认是false
-
callback
jsonp的回调名,
callback+"{"+result+"}";
Demo
代码
public class ReqParm { private String url = null; private Map<String, String> urlParm = null; private boolean post = false; private boolean https = false; private boolean respText = false; private String charset = "utf-8"; private Map<String, String> reqProperty = null; private boolean jsonp = false; private String respContentType = "text/plain"; private String callback = null; // getset... }
@WebServlet("/proxy") public class ProxyServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { exex(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { exex(req, resp); } private void exex(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("Access-Control-Allow-Origin", "*"); req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); ByteArrayOutputStream bos = null; OutputStream out = null; PrintWriter print = null; try { ReqParm o = initParm(req); ReqProxy reqProxy = new ReqProxy(o.getUrl()); reqProxy.setUrlParm(o.getUrlParm()); reqProxy.setHttps(o.isHttps()); reqProxy.setPost(o.isPost()); reqProxy.setReqProperty(o.getReqProperty()); bos = reqProxy.proxy(); if (o.isRespText()) { String result = bos.toString(o.getCharset()); if (o.isJsonp()) { result = o.getCallback() + "{" + result + "};"; } resp.setContentType(o.getRespContentType()); print = resp.getWriter(); print.write(result); print.flush(); } else { if (bos == null) { throw new Exception("bos为null"); } resp.setContentType("application/octet-stream"); resp.setHeader("Content-Disposition", "attachment;filename=\"proxy\""); out = resp.getOutputStream(); bos.writeTo(out); out.flush(); } } catch (Exception e) { resp.setContentType("application/json"); ResponseMessage responseMessage = new ResponseMessage(); responseMessage.setErrno(1); responseMessage.setMsg(e.getMessage()); if (print == null) { print = resp.getWriter(); } print.write(JsonUtils.toJson(responseMessage)); print.flush(); } finally { if (bos != null) { bos.close(); } if (out != null) { out.close(); } if (print != null) { print.close(); } } } private ReqParm initParm(HttpServletRequest req) throws Exception { try { ReqParm o = new ReqParm(); if (req.getParameter("respContentType") != null) { o.setRespContentType(req.getParameter("respContentType")); } if (req.getParameter("url") == null) { throw new Exception("url为空"); } else { o.setUrl(StringUtil.iso2utf(req.getParameter("url"))); } if (req.getParameter("urlParm") != null) { String parms = StringUtil.iso2utf(req.getParameter("urlParm")); Map<String, String> urlParm = new HashMap<String, String>(); String[] array = parms.split(";"); for (int i = 0; i < array.length; i++) { int index = array[i].indexOf(':'); urlParm.put(array[i].substring(0, index), array[i].substring(index + 1)); } o.setUrlParm(urlParm); } if (req.getParameter("post") != null && req.getParameter("post").equals("true")) { o.setPost(true); } if (req.getParameter("https") != null && req.getParameter("https").equals("true")) { o.setHttps(true); } if (req.getParameter("respText") != null && req.getParameter("respText").equals("true")) { o.setRespText(true); } if (req.getParameter("charset") != null) { o.setCharset(req.getParameter("charset")); } if (req.getParameter("reqProperty") != null) { Map<String, String> reqProperty = new HashMap<String, String>(); String[] array = req.getParameter("reqProperty").split(";"); for (int i = 0; i < array.length; i++) { int index = array[i].indexOf(':'); reqProperty.put(array[i].substring(0, index), array[i].substring(index + 1)); } o.setReqProperty(reqProperty); } if (req.getParameter("jsonp") != null && req.getParameter("jsonp").equals("true")) { o.setJsonp(true); if (req.getParameter("callback") != null) { o.setCallback(req.getParameter("callback")); o.setRespContentType("application/x-javascript"); } else { throw new Exception("jsonp为true没有指定callback"); } } return o; } catch (Exception e) { throw new Exception("参数初始化:" + e.getMessage()); } } }
public class ReqProxy { private String url = null; private boolean https = false; private Map<String, String> urlParm = null; private boolean post = false; private Map<String, String> reqProperty = null; @SuppressWarnings("unused") private ReqProxy() { } public ReqProxy(String url) { this.url = url; } // getset.... private void validation() throws Exception { if (url == null || url.equals("")) { throw new Exception("url 为空"); } else if (url.startsWith("http")) { throw new Exception("url不需要携带http(s)前缀"); } } private HttpURLConnection buildConnection() throws Exception { String reqUrl = url; HttpURLConnection httpURLConnection; if (!post) { reqUrl += buildQueryString(urlParm); } if (https) { HttpsURLConnection conn = (HttpsURLConnection) new URL("https://" + reqUrl).openConnection(); // 对证书不做检验 conn.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); httpURLConnection = conn; } else { httpURLConnection = (HttpURLConnection) new URL("http://" + reqUrl).openConnection(); } // 设置超时 httpURLConnection.setConnectTimeout(8000); httpURLConnection.setReadTimeout(8000); // 设置请求参数 if (reqProperty != null) { for (String key : reqProperty.keySet()) { httpURLConnection.setRequestProperty(key, reqProperty.get(key)); } } return httpURLConnection; } private String buildQueryString(Map<String, String> map) { if (map != null) { String result = "?"; for (String key : map.keySet()) { result += key + "=" + map.get(key) + "&"; } if (result.equals("?")) { return ""; } else { return result.substring(0, result.length() - 1); } } else { return ""; } } private ByteArrayOutputStream save(InputStream inputStream) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, length); } return byteArrayOutputStream; } public ByteArrayOutputStream proxy() throws Exception { validation(); HttpURLConnection conn = null; PrintWriter out = null; InputStream inputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; try { conn = buildConnection(); if (post) { conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); String parm = buildQueryString(urlParm); if (!parm.equals("")) { out = new PrintWriter(conn.getOutputStream()); out.print(parm); out.flush(); } inputStream = conn.getInputStream(); } else { inputStream = conn.getInputStream(); } byteArrayOutputStream = save(inputStream); } catch (Exception e) { throw new Exception(e); } finally { if (out != null) { out.close(); } if (conn != null) { conn.disconnect(); } if (inputStream != null) { inputStream.close(); } } return byteArrayOutputStream; } }
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。