欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

使用Filter拦截器如何实现请求跨域转发

程序员文章站 2022-03-12 22:35:44
目录filter拦截器实现请求跨域转发在使用filter实现转发后特做一次记录filter拦截器实现请求跨域转发因为公司项目需求,项目中前端请求需要通过一个类似中转的服务转发(请求在该服务中会重新包装...

filter拦截器实现请求跨域转发

因为公司项目需求,项目中前端请求需要通过一个类似中转的服务转发(请求在该服务中会重新包装一些通用参数)

在使用filter实现转发后特做一次记录

package com.unicloud.cce.filter; 
import com.alibaba.fastjson.json;
import com.unicloud.cce.common.restfulentity;
import com.unicloud.cce.service.cloudosservice;
import org.apache.commons.io.ioutils;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.http.*;
import org.springframework.stereotype.component;
import org.springframework.util.antpathmatcher;
import org.springframework.util.stringutils;
import org.springframework.web.client.resttemplate; 
import javax.servlet.*;
import javax.servlet.annotation.webfilter;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
import java.io.printwriter;
import java.util.*;
 
/**
 * @author skyxt
 * created 2019-06-11 18:46
 * email skyxt.yang@gmail.com
 */
@webfilter(filtername = "authfilter", urlpatterns = { "/*" })
@component
public class requestfilter implements filter { 
 
    //该处配置需要转发的路径
    public static final set<string> filter_url = collections.unmodifiableset(new hashset<>(arrays.aslist(
            "/config/*"
    )));
 
    @autowired
    private resttemplate resttemplate;
    @autowired
    private cloudosservice cloudosservice;  
    private final static logger logger = loggerfactory.getlogger(requestfilter.class); 
    @override
    public void init(filterconfig filterconfig) throws servletexception { 
    }
 
    @override
    public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception {
        if (!(request instanceof httpservletrequest) || !(response instanceof httpservletresponse)) {
            return;
        }
        httpservletrequest req = (httpservletrequest) request;
        httpservletresponse rsp = (httpservletresponse) response;
        antpathmatcher matcher = new antpathmatcher();
        optional<string> cloudip = optional.empty();
//        for (string url : filter_url) {
//            if (matcher.match(url, req.getrequesturi().substring(req.getcontextpath().length()))) {
//                cloudip = cloudosservice.cloudoslist("", "").stream().filter(cloudos ->
//                        cloudos.getid().equals(((httpservletrequest) request).getheader("cloudid"))
//                ).map(cloudos::getcloudip).findfirst();
//            }
//        }
        cloudip = optional.of("localhost");
        if (cloudip.ispresent()) {
            switch (req.getmethod()) {
                case "get": {
                    request(req, rsp, httpmethod.get, cloudip.get());
                    break;
                }
                case "post": {
                    request(req, rsp, httpmethod.post, cloudip.get());
                    break;
                }
                case "put": {
                    request(req, rsp, httpmethod.put, cloudip.get());
                    break;
                }
                case "patch": {
                    request(req, rsp, httpmethod.patch, cloudip.get());
                    break;
                }
                case "delete": {
                    request(req, rsp, httpmethod.delete, cloudip.get());
                    break;
                }
                default:{
                    logger.error("unknow request method:" + req.getmethod());
                    rsp.setcharacterencoding("utf-8");
                    try (printwriter out = rsp.getwriter()) {
                        out.write("请求方法未知");
                    } catch (exception e1) {
                        logger.error(e1.getmessage() + e1);
                    }
                } 
            }
        } else {
            chain.dofilter(request, response);
        }
    }
 
    @override
    public void destroy() { 
    }
 
    private void request(httpservletrequest req, httpservletresponse rsp, httpmethod method, string cloudip) throws ioexception {
        rsp.setcharacterencoding("utf-8");
        string requestbody = ioutils.tostring(req.getinputstream(), "utf-8");
        object body = null;
        if (stringutils.hastext(requestbody)) {
            body = json.parse(requestbody);
        }
        httpheaders headers = new httpheaders();
        enumeration<string> headernames = req.getheadernames();
        while (headernames.hasmoreelements()) {
            string name = headernames.nextelement();
            headers.add(name, req.getheader(name));
        }
        string url;
        if (stringutils.hastext(req.getquerystring())) {
            url = string.format(
                    "http://%s:15120%s?%s",
                    cloudip,
                    req.getrequesturi().substring(req.getcontextpath().length()),
                    req.getquerystring()
                    );
        } else {
            url = string.format(
                    "http://%s:15120%s",
                    cloudip,
                    req.getrequesturi().substring(req.getcontextpath().length())
            );
        }
        httpentity<object> httpentity = new httpentity<>(body, headers);
        responseentity<restfulentity> exchange = null;
        try {
            exchange = resttemplate.exchange(
                    url,
                    method,
                    httpentity,
                    restfulentity.class
            );
        } catch (exception e) {
            logger.error(e.getmessage(), e);
            try (printwriter out = rsp.getwriter()) {
                out.write("请求异常");
            } catch (exception e1) {
                logger.error(e1.getmessage() + e1);
            }
        }
        if (exchange != null) {
            exchange.getstatuscode();
            rsp.setstatus(exchange.getstatuscodevalue());
            exchange.getheaders().entryset().stream().foreach(entry -> {
                string value = entry.getvalue().tostring();
                rsp.addheader(entry.getkey(), value.substring(1, value.length()-1));
            });
            try (printwriter out = rsp.getwriter()) {
                out.write(json.tojsonstring(exchange.getbody()));
            } catch (exception e) {
                logger.error(e.getmessage(), e);
            }
        } else {
            logger.info("error: url:" + "http://" + cloudip + ":15120" + req.getrequesturi().substring(req.getcontextpath().length()));
            try (printwriter out = rsp.getwriter()) {
                out.write("请求异常");
            } catch (exception e1) {
                logger.error(e1.getmessage() + e1);
            }
        } 
    }
}

使用filter解决跨域

在web.xml配置拦截器

 <filter>
  <filter-name>servletfiltertest</filter-name>
  <filter-class>cn.test.intercepter.servletfiltertest</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>servletfiltertest</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

过滤器代码

import org.springframework.web.bind.annotation.requestmethod;
import javax.servlet.*;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
public class servletfiltertest implements filter {
    @override
    public void init(filterconfig filterconfig) throws servletexception {
    }
    @override
    public void dofilter(servletrequest servletrequest, servletresponse servletresponse, filterchain filterchain) throws ioexception, servletexception {
        httpservletrequest httpservletrequest = (httpservletrequest) servletrequest;
        httpservletrequest.getsession();
        httpservletresponse httpresponse = (httpservletresponse) servletresponse;
        httpresponse.setheader("access-control-allow-origin", "*");
        httpresponse.setheader("access-control-allow-methods", "*");
        httpresponse.setheader("access-control-max-age", "3600");
        httpresponse.setheader("access-control-allow-headers",
                "origin, x-requested-with, content-type, accept, connection, user-agent, cookie");
        httpresponse.setheader("access-control-allow-credentials", "true");
        httpresponse.setheader("content-type", "application/json");
        httpresponse.setheader("cache-control", "no-cache, must-revalidate");
        if (httpservletrequest.getmethod().equals(requestmethod.options.name())) {
            return ;
        }
        filterchain.dofilter(httpservletrequest, httpresponse);
    }
    @override
    public void destroy() {
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。