使用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() { } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
上一篇: kotlin中的泛型
下一篇: 历史上的杯酒释兵权,不止一顿饭那么简单