广告位联系
返回顶部
分享到

详解使用Filter拦截器实现请求跨域转发

java 来源:转载 作者:秩名 发布时间:2021-08-29 07:54:23 人浏览
摘要

Filter拦截器实现请求跨域转发 因为公司项目需求,项目中前端请求需要通过一个类似中转的服务转发(请求在该服务中会重新包装一些通用参数) 在使用Filter实现转发后特做一次记录 package com.unicloud.cce.Filter; import com.alibaba.fastjson.JSON;import co

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() {
    }
}


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/weixin_37774620/article/details/91544007
相关文章
  • SpringBoot自定义错误处理逻辑介绍

    SpringBoot自定义错误处理逻辑介绍
    1. 自定义错误页面 将自定义错误页面放在 templates 的 error 文件夹下,SpringBoot 精确匹配错误信息,使用 4xx.html 或者 5xx.html 页面可以打印错误
  • Java实现手写一个线程池的代码

    Java实现手写一个线程池的代码
    线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个知识点,那么大家知道它的实现原理和
  • Java实现断点续传功能的代码

    Java实现断点续传功能的代码
    题目实现:网络资源的断点续传功能。 二、解题思路 获取要下载的资源网址 显示网络资源的大小 上次读取到的字节位置以及未读取的字节
  • 你可知HashMap为什么是线程不安全的
    HashMap 的线程不安全 HashMap 的线程不安全主要体现在下面两个方面 在 jdk 1.7 中,当并发执行扩容操作时会造成环形链和数据丢失的情况 在
  • ArrayList的动态扩容机制的介绍

    ArrayList的动态扩容机制的介绍
    对于 ArrayList 的动态扩容机制想必大家都听说过,之前的文章中也谈到过,不过由于时间久远,早已忘却。 所以利用这篇文章做做笔记,加
  • JVM基础之字节码的增强技术介绍

    JVM基础之字节码的增强技术介绍
    字节码增强技术 在上文中,着重介绍了字节码的结构,这为我们了解字节码增强技术的实现打下了基础。字节码增强技术就是一类对现有字
  • Java中的字节码增强技术

    Java中的字节码增强技术
    1.字节码增强技术 字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。 参考地址 2.常见技术 技术分类 类
  • Redis BloomFilter布隆过滤器原理与实现

    Redis BloomFilter布隆过滤器原理与实现
    Bloom Filter 概念 布隆过滤器(英语:Bloom Filter)是1970年由一个叫布隆的小伙子提出的。它实际上是一个很长的二进制向量和一系列随机映射
  • Java C++算法题解leetcode801使序列递增的最小交换次

    Java C++算法题解leetcode801使序列递增的最小交换次
    题目要求 思路:状态机DP 实现一:状态机 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int minSwap(int[] nums1, int[] nums2) { int n
  • Mybatis结果集映射与生命周期介绍

    Mybatis结果集映射与生命周期介绍
    一、ResultMap结果集映射 1、设计思想 对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了 2、resultMap的应用场
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计