JAVA中间转发层开发

该项目为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 用来初始化Log4J的配置
LoginFilter   用来拦截所有的web中的请求
CookieCallBack  回调接口
MiddleServlet  转发请求其他域的API的Servlet   

JAVA中间转发层开发_第1张图片


下面发送一个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中的处理流程:
1、先从 HttpServletRequest 中得到请求的url,然后将其他域名和这个url拼接成完整的API请求的URL。
2、再从 HttpServletRequest 中得到请求的cookie(登录之后才会有cookie)
3、从 HttpServletRequest  中得到请求的流(POST才有此步骤) 
4、HTTP请求API完整的URL(在请求之前,对http进行cookie设置)
5、API请求登录接口之后会返回token,将token设置到 HttpServletResponse 中去,这样H5端和中间层建立了登录授权关系,而中间层和API建立了登录授权关系 

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 getCookie(HttpServletRequest request) {
          javax.servlet.http.Cookie[] requestCookies = ((HttpServletRequest) request).getCookies();
          List cookies = new ArrayList();
          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 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  类可以参考demo中
下载地址: http://download.csdn.net/detail/q908555281/9729781


你可能感兴趣的:(JAVA,WEB开发技术)