使用Filter攔截器如何實現(xiàn)請求跨域轉(zhuǎn)發(fā)
更新時間:2021年08月28日 11:37:28 作者:成都楊小天
這篇文章主要介紹了使用Filter攔截器如何實現(xiàn)請求跨域轉(zhuǎn)發(fā),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
Filter攔截器實現(xiàn)請求跨域轉(zhuǎn)發(fā)
因為公司項目需求,項目中前端請求需要通過一個類似中轉(zhuǎn)的服務轉(zhuǎn)發(fā)(請求在該服務中會重新包裝一些通用參數(shù))
在使用Filter實現(xiàn)轉(zhuǎn)發(fā)后特做一次記錄
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 { //該處配置需要轉(zhuǎn)發(fā)的路徑 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() { } }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
springboot整合mybatis plus與druid詳情
這篇文章主要介紹了springboot整合mybatis plus與druid詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的下伙伴可以參考一下2022-09-09SpringSecurity6自定義JSON登錄的實現(xiàn)
目前最新版的Spring Boot已經(jīng)到了3.0.5了,隨之而來Spring Security 目前的版本也到了6.0.2了,Spring Security寫法的變化特別多,本文就來介紹下,感興趣的可以了解一下2023-12-12JDBC插入數(shù)據(jù)返回數(shù)據(jù)主鍵代碼實例
這篇文章主要介紹了JDBC插入數(shù)據(jù)返回數(shù)據(jù)主鍵代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-11-11