springboot实现超轻量级⽹关的⽅法(反向代理、转发)
在我们的rest服务中,需要暴露⼀个中间件的接⼝给⽤户,但是需要经过rest服务的认证,这是典型的⽹关使⽤场景。可以引⼊⽹关组件来搞定,但是引⼊zuul等中间件会增加系统复杂性,这⾥实现⼀个超轻量级的⽹关,只实现请求转发,认证等由rest服务的spring security来搞定。
如何进⾏请求转发呢?熟悉⽹络请求的同学应该很清楚,请求⽆⾮就是请求⽅式、HTTP header,以及请求body,我们将这些信息取出来,透传给转发的url即可。
举例:
/graphdb/** 转发到 Graph_Server/**
获取转发⽬的地址:
private String createRedictUrl(HttpServletRequest request, String routeUrl, String prefix) {
String queryString = QueryString();
return routeUrl + RequestURI().replace(prefix, "") +
(queryString != null ? "?" + queryString : "");
}
解析请求头和内容
然后从request中提取出header、body等内容,构造⼀个RequestEntity,后续可以⽤RestTemplate来请求。
private RequestEntity createRequestEntity(HttpServletRequest request, String url) throws URISyntaxException, IOException {
String method = Method();
HttpMethod httpMethod = solve(method);
MultiValueMap<String, String> 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 = InputStream();
pyToByteArray(inputStream);
}
private MultiValueMap<String, String> parseRequestHeader(HttpServletRequest request) {
HttpHeaders headers = new HttpHeaders();
List<String> headerNames = Collections.HeaderNames());
for (String headerName : headerNames) {
List<String> headerValues = Collections.Headers(headerName));
for (String headerValue : headerValues) {
headers.add(headerName, headerValue);
}
}
return headers;
}
透明转发
最后⽤RestTemplate来实现请求:
private ResponseEntity<String> route(RequestEntity requestEntity) {
RestTemplate restTemplate = new RestTemplate();
hange(requestEntity, String.class);
}
全部代码
以下是轻量级转发全部代码:
import org.springframework.http.*;
import org.springframework.stereotype.Service;
springboot原理书籍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.URI;
import java.URISyntaxException;
import java.util.Collections;
import java.util.List;
@Service
public class RoutingDelegate {
public ResponseEntity<String> redirect(HttpServletRequest request, HttpServletResponse response,String routeUrl, String prefix) {
try {
// build up the redirect URL
String redirectUrl = createRedictUrl(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 createRedictUrl(HttpServletRequest request, String routeUrl, String prefix) {
String queryString = QueryString();
return routeUrl + RequestURI().replace(prefix, "") +
(queryString != null ? "?" + queryString : "");
}
private RequestEntity createRequestEntity(HttpServletRequest request, String url) throws URISyntaxException, IOException {
String method = Method();
HttpMethod httpMethod = solve(method);
MultiValueMap<String, String> headers = parseRequestHeader(request);
byte[] body = parseRequestBody(request);
return new RequestEntity<>(body, headers, httpMethod, new URI(url));
}
private ResponseEntity<String> route(RequestEntity requestEntity) {
RestTemplate restTemplate = new RestTemplate();
hange(requestEntity, String.class);
}
private byte[] parseRequestBody(HttpServletRequest request) throws IOException {
InputStream inputStream = InputStream();
pyToByteArray(inputStream);
}
private MultiValueMap<String, String> parseRequestHeader(HttpServletRequest request) {
HttpHeaders headers = new HttpHeaders();
List<String> headerNames = Collections.HeaderNames());
for (String headerName : headerNames) {
List<String> headerValues = Collections.Headers(headerName));
for (String headerValue : headerValues) {
headers.add(headerName, headerValue);
}
}
return headers;
}
}
Spring 集成
Spring Controller,RequestMapping⾥把GET \ POST\PUT\DELETE ⽀持的请求带上,就能实现转发了。
@RestController
@RequestMapping(GraphDBController.DELEGATE_PREFIX)
@Api(value = "GraphDB", tags = {
"graphdb-Api"
})
public class GraphDBController {
@Autowired
GraphProperties graphProperties;
public final static String DELEGATE_PREFIX = "/graphdb";
@Autowired
private RoutingDelegate routingDelegate;
@RequestMapping(value = "/**", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity catchAll(HttpServletRequest request, HttpServletResponse response) {
direct(request, response, GraphServer(), DELEGATE_PREFIX);
}
}
到此这篇关于spring boot实现超轻量级⽹关(反向代理、转发)的⽂章就介绍到这了,更多相关spring boot轻量级⽹关内容请搜索以前的⽂章或继续浏览下⾯
的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论