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

