(资料图)
在我们的rest服务中,需要暴露一个中间件的接口给用户,但是需要经过rest服务的认证,这是典型的网关使用场景。可以引入网关组件来搞定,但是引入zuul等中间件会增加系统复杂性,这里实现一个超轻量级的网关,只实现请求转发,认证等由rest服务的spring security来搞定。
如何进行请求转发呢? 熟悉网络请求的同学应该很清楚,请求无非就是请求方式、HTTP header,以及请求body,我们将这些信息取出来,透传给转发的url即可。
举例:
/router/** 转发到 businessServer/**
private String createRedirectUrl(HttpServletRequest request, String routeUrl, String prefix) { String queryString = request.getQueryString(); return routeUrl + request.getRequestURI().replace(prefix, "") + (queryString != null ? "?" + queryString : ""); }
然后从request中提取出header、body等内容,构造一个RequestEntity,后续可以用RestTemplate来请求。
private RequestEntity createRequestEntity(HttpServletRequest request, String url) throws URISyntaxException, IOException { String method = request.getMethod(); HttpMethod httpMethod = HttpMethod.resolve(method); MultiValueMap headers = parseRequestHeader(request); byte[] body = parseRequestBody(request); return new RequestEntity<>(body, headers, httpMethod, new URI(url)); } private byte[] parseRequestBody(HttpServletRequest request) throws IOException { InputStream inputStream = request.getInputStream(); return StreamUtils.copyToByteArray(inputStream); } private MultiValueMap parseRequestHeader(HttpServletRequest request) { HttpHeaders headers = new HttpHeaders(); List headerNames = Collections.list(request.getHeaderNames()); for (String headerName : headerNames) { List headerValues = Collections.list(request.getHeaders(headerName)); for (String headerValue : headerValues) { headers.add(headerName, headerValue); } } return headers; }
最后用RestTemplate来实现请求:
private ResponseEntity route(RequestEntity requestEntity) { RestTemplate restTemplate = new RestTemplate(); return restTemplate.exchange(requestEntity, String.class); }
以下是轻量级转发全部代码:
import com.jyw.router.miniapp.service.IRouterService;import org.springframework.http.*;import org.springframework.stereotype.Service;import org.springframework.util.MultiValueMap;import org.springframework.util.StreamUtils;import org.springframework.web.client.RestTemplate;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.InputStream;import java.net.URI;import java.net.URISyntaxException;import java.util.Collections;import java.util.List;/** * @author 黑子桑 * @ClassName IRouterServiceImpl * @Description TODO * @Date 2023/4/20 13:32 **/@Servicepublic class RouterServiceImpl implements IRouterService { @Override public ResponseEntity redirect(HttpServletRequest request, HttpServletResponse response,String routeUrl, String prefix) { try { // build up the redirect URL String redirectUrl = createRedirectUrl(request,routeUrl, prefix); RequestEntity requestEntity = createRequestEntity(request, redirectUrl); return route(requestEntity); } catch (Exception e) { return new ResponseEntity("REDIRECT ERROR", HttpStatus.INTERNAL_SERVER_ERROR); } } private String createRedirectUrl(HttpServletRequest request, String routeUrl, String prefix) { String queryString = request.getQueryString(); return routeUrl + request.getRequestURI().replace(prefix, "") + (queryString != null ? "?" + queryString : ""); } private RequestEntity createRequestEntity(HttpServletRequest request, String url) throws URISyntaxException, IOException { String method = request.getMethod(); HttpMethod httpMethod = HttpMethod.resolve(method); MultiValueMap headers = parseRequestHeader(request); byte[] body = parseRequestBody(request); return new RequestEntity<>(body, headers, httpMethod, new URI(url)); } private ResponseEntity route(RequestEntity requestEntity) { RestTemplate restTemplate = new RestTemplate(); return restTemplate.exchange(requestEntity, String.class); } private byte[] parseRequestBody(HttpServletRequest request) throws IOException { InputStream inputStream = request.getInputStream(); return StreamUtils.copyToByteArray(inputStream); } private MultiValueMap parseRequestHeader(HttpServletRequest request) { HttpHeaders headers = new HttpHeaders(); List headerNames = Collections.list(request.getHeaderNames()); for (String headerName : headerNames) { List headerValues = Collections.list(request.getHeaders(headerName)); for (String headerValue : headerValues) { headers.add(headerName, headerValue); } } return headers; }}
关键词:
关于我们 广告服务 手机版 投诉文章:435 226 40@qq.com
Copyright (C) 1999-2022 baidu.baiduer.com.cn baidu爱好者 版权所有 联系网站:435 226 40@qq.com