该项目为web项目,采用的AJAX+API方式进行数据交互,为了避免AJAX跨域,H5端采用AJAX请求数据时候,JAVA代码进行拦截,并请求到另外一个域名的接口。
流程:
1、在web.xml里面注册一个LoginFilter,用来监听和拦截所有web的请求。
2、在web.xml里面注册一个Servlet,将1中的拦截到的数据需要请求API接口的转发到Servlet中。
3、根据Servlet中的GET和POST请求来对不同的 ajax请求做http请求。
为什么要采用中间层转发?
个人认为:当第三方API出现问题的时候,可以在自己的中间层做一些处理,不会对前端造成影响,做到业务隔离。
比如:调用第三方的校验手机号码归属地的接口,如果出现挂掉的情况,可以在中间层立马切换到另外一个第三方通道
工程目录结构如下图所示:
InitialServlet
LoginFilter
CookieCallBack
MiddleServlet
下面发送一个ajax的请求:
function create_qrcode(){
ajax({
type:'GET',
url : "/api/user/get_login_barcode",
success : function(response){
var rs = eval("("+response+")");
if(rs.code == "0"){
xxxxxxxx
}
}
});
}
然后在LoginFilter中进行拦截处理,代码如下:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
* 登录过滤器
*
* @author zhuwenjun 20140506
*
*/
public class LoginFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest request = (HttpServletRequest) req;
response.setContentType( "text/html; charset=utf-8" );
response.setCharacterEncoding( "utf-8");
//得到请求的URI
String url=request.getRequestURI();
//因为所有的API请求都会带 api的字符串,请求页面的路径不会携带这个参数,在这里做校验,如果是API的请求就直接转发到MiddleServlet中
if(url.contains( "api/")){
//将请求的参数给设置过去
req.setAttribute( "path", url);
req.getServletContext().getRequestDispatcher( "/servlet/MiddleServlet" ).forward(req, response);
} else{
chain.doFilter(req, response);
return;
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
MiddleServlet中的处理流程:
HttpServletRequest
HttpServletRequest
HttpServletRequest
4、HTTP请求API完整的URL(在请求之前,对http进行cookie设置)
HttpServletResponse
package com.baimi.walletadmin.pc;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.cookie.Cookie;
import org.apache.log4j.Logger;
import com.baimi.walletadmin.pc.util.HttpsRequest;
import com.baimi.walletadmin.pc.util.RegexUtil;
import com.baimi.walletadmin.pc.util.Util;
public class MiddleServlet extends HttpServlet {
private Logger log_info = Logger.getLogger("base");
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String returnMsg = HttpsRequest.executeGet(getReqUrl(req), getCookie(req),new CookieUtil(req, resp));
Util.returnMsg(resp, returnMsg);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String returnMsg = HttpsRequest.executePost(getReqUrl(req), getCookie(req),req.getInputStream(), new CookieUtil(req, resp));
Util.returnMsg(resp, returnMsg);
}
private List<javax.servlet.http.Cookie> getCookie(HttpServletRequest request) {
javax.servlet.http.Cookie[] requestCookies = ((HttpServletRequest) request).getCookies();
List<javax.servlet.http.Cookie> cookies = new ArrayList<javax.servlet.http.Cookie>();
if (requestCookies != null) {
for (javax.servlet.http.Cookie cookie : requestCookies) {
if (Constants.TOKEN_COOKIE_NAME.equals(cookie.getName()) || Constants.ZG_COOKIE_NAME.equals(cookie.getName())) {
cookies.add(cookie);
}
}
}
return cookies;
}
//从HttpServletRequest中得到请求的url,并拼接成访问第三方API的url
private String getReqUrl(HttpServletRequest request) {
String path = String.valueOf(request.getAttribute("path"));
if (path.contains("api/")) {
String retUrl = Constants.REQ_HOST + path.substring(path.indexOf("api/"), path.length());
String params = request.getQueryString();
if (RegexUtil.isEmpty(params)) {
retUrl = retUrl + "?" + params;
}
return retUrl;
} else {
return null;
}
}
//接口实现类
class CookieUtil implements CookieCallBack {
private HttpServletRequest request;
private HttpServletResponse response;
public CookieUtil(HttpServletRequest request, HttpServletResponse response) {
super();
this.request = request;
this.response = response;
}
//登录第三方API之后要将第三方返回的cookie设置到HttpServletResponse中
@Override
public void doLogin(List<Cookie> list) {
for (Cookie cookie : list) {
if (Constants.TOKEN_COOKIE_NAME.equals(cookie.getName()) || Constants.ZG_COOKIE_NAME.equals(cookie.getName())) {
javax.servlet.http.Cookie cook = new javax.servlet.http.Cookie(cookie.getName(),cookie.getValue());
cook.setPath("/");
cook.setMaxAge(Constants.COOKIE_TIME);
((HttpServletResponse) response).addCookie(cook);
break;
}
}
}
//退出的操作需要将HttpServletResponse中的cookie给清空掉
@Override
public void doLogout() {
request.getSession().invalidate();// 清空session
javax.servlet.http.Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (javax.servlet.http.Cookie cookie : cookies) {
if (Constants.TOKEN_COOKIE_NAME.equals(cookie.getName())) {
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);
break;
}
}
}
}
}
}
HttpsRequest