SpringBoot用Filter实现轻量级网关,实现拦截请求和转发请求 您所在的位置:网站首页 springboot代理转发服务 SpringBoot用Filter实现轻量级网关,实现拦截请求和转发请求

SpringBoot用Filter实现轻量级网关,实现拦截请求和转发请求

#SpringBoot用Filter实现轻量级网关,实现拦截请求和转发请求| 来源: 网络整理| 查看: 265

注:gateway网关当然可以实现这个功能啊啊,不要问我为什么不使用网关,是因为那个项目用不了网关,只能用filter做一个低配版

应用场景:本服务将请求转发到其他服务器,将结果返回

浏览器请求:https://192.168.0.199:7000/demo1/examine/pulse 希望请求转发到 https://192.168.0.199:7004/demo2/examine/pulse

想法:一开始想用请求的转发和重定向实现,但是转发针对的是同一个服务器,重定向又不能携带参数,所以用SpringBoot的RestTemplate发送http请求,得到结果后在网关返回数据给客户端

转发和重定向的特点和区别

1.转发

1、转发是服务器端行为 2、转发整个过程浏览器端只做了一次请求 3、转发浏览器地址不变 4、在转发过程中request域中的数据不会丢失 5、转发只能将请求转发给同一个web应用中的组件

2.重定向

1、重定向是客户端行为 2、重定向是浏览器做了至少两次的访问请求 3、重定向浏览器地址改变 4、重定向两次跳转之间request域中信息数据会丢失(新的request会替代旧request但是不会继承旧request中的数据) 5、重定向可以指向任何资源,包括当前应用程序中的其他资源、同一站点上其他应用程序中的资源以及其他站点的资源

流程:写了一段不怎么好的代码,单独的一个SpringBoot启动,作为网关,请求进来以后进行拦截,是本服务处理的就进入过滤链,要转发到别的服务的就解析获取请求类型、请求头、请求体,然后使用RestTemplate携带这些内容原封不动的发送出去,返回请求的结果result到网关,然后返回客户端。 写的不好,但是我觉得这解析请求中的请求类型、请求头、请求体的方法可以记一下,毕竟下次我就记不起来了hha

import lombok.extern.log4j.Log4j2; import org.springframework.core.Ordered; import org.springframework.http.*; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.util.StreamUtils; 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 javax.sound.midi.Soundbank; import java.io.*; import java.net.*; import java.nio.charset.StandardCharsets; import java.util.*; @WebFilter @Component @Log4j2 public class DemoFilter implements Filter, Ordered { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{ System.out.println("================进入过滤器================="); HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; String requestURI = req.getRequestURI(); if ("/demo1/test".equals(requestURI)) { // 要处理的请求,本服务 chain.doFilter(request,response); } else { // 转发请求,如果是同一个服务器可以直接调用转发请求的方法,这里要做的是转发请求另一个服务的接口,然后返回请求结果 // 1、地址栏有传参数需要进行拼接参数 String queryString = req.getQueryString();//地址栏参数 if (queryString != null) { // 地址有参数,拼接 requestURI = requestURI + "?" +queryString; } // 2、拼接转发的IP和端口 InetAddress ip; String IP = null; try { ip = Inet4Address.getLocalHost(); IP = ip.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } String url = "http://" + IP + ":7004" + requestURI; // 3、请求类型 String method = req.getMethod(); HttpMethod httpMethod = HttpMethod.resolve(method);//method // 4、请求头 MultiValueMap headers = parseRequestHeader(req);//header // 5、请求体 byte[] body = parseRequestBody(req);//body // 6、封装发singhttp请求 RequestEntity requestEntity = new RequestEntity(body, headers, httpMethod, URI.create(redirectUrl)); RestTemplate restTemplate = new RestTemplate(); //编码格式转换 restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8)); ResponseEntity result = restTemplate.exchange(requestEntity, String.class); // 将转发请求得到的结果和响应头返回客户端 String resultBody = result.getBody(); HttpHeaders resultHeaders = result.getHeaders(); MediaType contentType = resultHeaders.getContentType(); if (contentType != null) { resp.setContentType(contentType.toString()); } resp.setCharacterEncoding("UTF-8");// 在getWriterz之前执行,否则不生效 PrintWriter writer = resp.getWriter(); writer.write(resultBody); writer.flush(); } } @Override public void destroy() { System.out.println("================destroy()================="); } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } /** * request body * @param request * @return * @throws IOException */ private byte[] parseRequestBody(HttpServletRequest request) throws IOException { InputStream inputStream = request.getInputStream(); return StreamUtils.copyToByteArray(inputStream); } /** * request header * @param request * @return */ private MultiValueMap parseRequestHeader(HttpServletRequest request) { HttpHeaders httpHeaders = new HttpHeaders(); List headerNames = Collections.list(request.getHeaderNames()); for(String headerName : headerNames) { List headerValues = Collections.list(request.getHeaders(headerName)); for (String headerValue : headerValues) { httpHeaders.add(headerName, headerValue); } } return httpHeaders; } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有