当前位置: 首页 > news >正文

大连免费网站建设软件开发各阶段工作量比例

大连免费网站建设,软件开发各阶段工作量比例,有什么可以做兼职的正规网站,100个万能营销方案目录 1、基本的对象1.1 配置类1.2 实体DTO1.3 路由代理拓展器1.4 请求对象 RestTemplate 2、核心转发代码3、暴露接口4、基础配置 前言#xff1a;想实现一个轻量级的接口反向代理和转发的一个接口服务#xff0c;可以通过这个服务做一些需要认证才能访问的接口给到前端使用想实现一个轻量级的接口反向代理和转发的一个接口服务可以通过这个服务做一些需要认证才能访问的接口给到前端使用这样就实现了一种认证可以调用多种第三方系统的服务。 基本逻辑就是将请求的请求方式、请求头、请求体提取出来将这些信息转发到另外一个接口 假设当前接口在 bizbook-api 这个服务上可以实现 /bizbook-api/common/** 的接口转发到 http://192.168.50.43:7612/** 列子访问/bizbook-api/common/bizweb-api/sj/list 就相当于访问 /bizweb-api/sj/list 1、基本的对象 1.1 配置类 import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component;import java.util.List;/*** 路由代理配置*/ Configuration ConfigurationProperties(prefix delegate.config.api, ignoreUnknownFields false) public class RouterDelegateProperties {/*** 网关地址*/String rootPath;/*** 服务名称, 服务名称和服务网关和服务拓展器一一对应, 服务网关和服务拓展器没有则用default代替*/ListString serviceName;/*** 服务网关, 服务名称和服务网关和服务拓展器一一对应, 服务网关和服务拓展器没有则用default代替*/ListString serviceRoot;/*** 服务拓展器, 服务名称和服务网关和服务拓展器一一对应, 服务网关和服务拓展器没有则用default代替*/ListString serviceExtractor;public String getRootPath() {return rootPath;}public void setRootPath(String rootPath) {this.rootPath rootPath;}public ListString getServiceName() {return serviceName;}public void setServiceName(ListString serviceName) {this.serviceName serviceName;}public ListString getServiceRoot() {return serviceRoot;}public void setServiceRoot(ListString serviceRoot) {this.serviceRoot serviceRoot;}public ListString getServiceExtractor() {return serviceExtractor;}public void setServiceExtractor(ListString serviceExtractor) {this.serviceExtractor serviceExtractor;} }1.2 实体DTO import java.io.Serializable;/*** 代理路由配置 DTO*/ public class RouterDelegateConfigDTO implements Serializable {private static final long serialVersionUID 1L;/*** 网关地址*/private String rootPath;/*** 服务名称*/private String serviceName;/*** 服务名称地址*/private String serviceRoot;/*** 服务名称处理器*/private String serviceExtractor;public String getRootPath() {return rootPath;}public void setRootPath(String rootPath) {this.rootPath rootPath;}public String getServiceName() {return serviceName;}public void setServiceName(String serviceName) {this.serviceName serviceName;}public String getServiceRoot() {return serviceRoot;}public void setServiceRoot(String serviceRoot) {this.serviceRoot serviceRoot;}public String getServiceExtractor() {return serviceExtractor;}public void setServiceExtractor(String serviceExtractor) {this.serviceExtractor serviceExtractor;} }1.3 路由代理拓展器 import org.springframework.http.HttpHeaders; import zsoft.gov.datacenter.biztable.common.dto.router.RouterDelegateConfigDTO;import javax.servlet.http.HttpServletRequest;/*** 路由代理拓展器*/ public interface RouterDelegateExtractor {/*** 处理请求url, 返回null则使用通用处理逻辑** param request 请求体对象* param configDTO 服务配置对象* param prefix 代理前缀* return*/String getRequestRootUrl(HttpServletRequest request, RouterDelegateConfigDTO configDTO, String prefix);/*** 处理请求头** param request 请求体对象* param headers 请求头*/void parseRequestHeader(HttpServletRequest request, HttpHeaders headers);/*** 处理请求体, 返回null则使用通用处理逻辑** param request 请求体对象* return*/byte[] parseRequestBody(HttpServletRequest request);}1.4 请求对象 RestTemplate import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.RestTemplate;import java.io.IOException; import java.nio.charset.Charset; import java.util.List;Configuration public class FetchApiRestTemplateConfig {Bean({fetchApiRestTemplate})Autowiredpublic RestTemplate restTemplate(Qualifier(fetchApiClientHttpRequestFactory) ClientHttpRequestFactory factory) {RestTemplate restTemplate new RestTemplate(factory);restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {Overridepublic void handleError(ClientHttpResponse response) throws IOException { // if (response.getRawStatusCode() ! 401 response.getRawStatusCode() ! 404) { // super.handleError(response); // }// 处理返回 4xx 的状态码时不抛出异常if (!response.getStatusCode().is4xxClientError()) {super.handleError(response);}}});// 中文乱码问题ListHttpMessageConverter? httpMessageConverters restTemplate.getMessageConverters();httpMessageConverters.stream().forEach(httpMessageConverter - {if (httpMessageConverter instanceof StringHttpMessageConverter) {StringHttpMessageConverter messageConverter (StringHttpMessageConverter) httpMessageConverter;messageConverter.setDefaultCharset(Charset.forName(UTF-8));}});return restTemplate;}Bean({fetchApiClientHttpRequestFactory})public ClientHttpRequestFactory simpleClientHttpRequestFactory() {SimpleClientHttpRequestFactory factory new SimpleClientHttpRequestFactory();factory.setReadTimeout(1000 * 50); // 读取超时(毫秒)factory.setConnectTimeout(1000 * 10); // 连接超时(毫秒)return factory;}}2、核心转发代码 import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.util.StreamUtils; import org.springframework.web.client.RestTemplate; import zsoft.gov.datacenter.biztable.common.config.RouterDelegateProperties; import zsoft.gov.datacenter.biztable.common.dto.router.RouterDelegateConfigDTO; import zsoft.gov.datacenter.biztable.common.response.Result;import javax.annotation.Resource; 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; import java.util.Map; import java.util.concurrent.ConcurrentHashMap;/*** 路由代理*/ Service public class RouterDelegate implements ApplicationRunner {protected Logger logger LoggerFactory.getLogger(getClass());private static MapString, RouterDelegateConfigDTO configMap;ResourceQualifier(fetchApiRestTemplate)private RestTemplate restTemplate;Resourceprivate RouterDelegateProperties properties;Resourceprivate MapString, RouterDelegateExtractor stringRouterDelegateExtractorMap;/*** 初始化配置类** param args* throws Exception*/Overridepublic void run(ApplicationArguments args) throws Exception {boolean intiFlag false;logger.info( -----开始初始化路由代理配置类!);/*** 最终configMap效果* {* 服务名称: {* rootPath: 系统网关地址,* serviceName: 服务名称,* serviceRoot: 服务网关,* serviceExtractor: 服务拓展器,* }* }*/String rootPath properties.getRootPath();ListString serviceName properties.getServiceName();ListString serviceRoot properties.getServiceRoot();ListString serviceExtractor properties.getServiceExtractor();// 服务名称, 服务名称和服务网关和服务处理器一一对应, 如果没有对应的服务网关和服务处理器, 则用英文逗号隔开if (StringUtils.isNotBlank(rootPath) CollectionUtils.isNotEmpty(serviceName) CollectionUtils.isNotEmpty(serviceExtractor) CollectionUtils.isNotEmpty(serviceRoot) serviceName.size() serviceRoot.size() serviceName.size() serviceExtractor.size()) {intiFlag true;// 初始化大小避免扩容int initialCapacity (int) (serviceName.size() / 0.75) 1;configMap new ConcurrentHashMap(initialCapacity);for (int i 0; i serviceName.size(); i) {RouterDelegateConfigDTO dto new RouterDelegateConfigDTO();String serName serviceName.get(i);dto.setRootPath(rootPath);dto.setServiceName(serName);// default 是占位符, 配置成default相当于没有配置dto.setServiceRoot(default.equals(serviceRoot.get(i)) ? null : serviceRoot.get(i));dto.setServiceExtractor(default.equals(serviceExtractor.get(i)) ? null : serviceExtractor.get(i));configMap.put(serName, dto);}}if (intiFlag) logger.info( 初始化路由代理配置类成功!);else logger.error( 初始化路由代理配置类失败!);}public ResponseEntitybyte[] redirect(HttpServletRequest request, HttpServletResponse response, String prefix, String serviceName) {String requestURI request.getRequestURI();RouterDelegateConfigDTO currentConfig getCurrentServiceConfig(serviceName);if (currentConfig null) {return buildErrorResponseEntity(SERVICE ERROR! 服务不存在!, HttpStatus.NOT_FOUND);}RouterDelegateExtractor extractorCallBack getRouterDelegateExtractor(serviceName);try {// 创建urlString redirectUrl createRequestUrl(request, currentConfig, prefix, extractorCallBack);logger.info( redirectUrl代理后的完整地址: [{}], redirectUrl);RequestEntity requestEntity createRequestEntity(request, redirectUrl, extractorCallBack);// return route(request, redirectUrl, extractorCallBack);ResponseEntitybyte[] result route(requestEntity);if (result.getHeaders() ! null result.getHeaders().containsKey(HttpHeaders.TRANSFER_ENCODING)) {// 移除响应头 Transfer-Encoding, 因为高版本的nginx会自动添加该响应头, 多个响应值nginx会报错// 多个响应值nginx报错: *6889957 upstream sent duplicate header line: Transfer-Encoding: chunked, previous value: Transfer-Encoding: chunked while reading response header from upstreamHttpHeaders headers HttpHeaders.writableHttpHeaders(result.getHeaders());headers.remove(HttpHeaders.TRANSFER_ENCODING);}//logger.info( [{}] 代理成功, 请求耗时: [{}], requestURI, System.currentTimeMillis() - l1);return result;} catch (Exception e) {logger.error(REDIRECT ERROR, e);//logger.error( [{}] 代理失败, 请求耗时: [{}], requestURI, System.currentTimeMillis() - l1);return buildErrorResponseEntity(REDIRECT ERROR! e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);}}private ResponseEntity buildErrorResponseEntity(String msg, HttpStatus httpStatus) {HttpHeaders headers new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);Result body Result.build(httpStatus.value(), msg);return new ResponseEntity(body, headers, httpStatus);}/*** 获取当前服务配置** param serviceName* return*/public RouterDelegateConfigDTO getCurrentServiceConfig(String serviceName) {if (configMap null || !configMap.containsKey(serviceName)) {return null;}return configMap.get(serviceName);}/*** 获取当前路由服务拓展器** param serviceName* return*/private RouterDelegateExtractor getRouterDelegateExtractor(String serviceName) {RouterDelegateConfigDTO currentConfig getCurrentServiceConfig(serviceName);if (currentConfig null) {return null;}String serviceExtractor currentConfig.getServiceExtractor();if (StringUtils.isBlank(serviceExtractor)) {return null;}RouterDelegateExtractor extractor stringRouterDelegateExtractorMap.get(serviceExtractor RouterDelegateExtractor);return extractor;}/*** 创建请求地址** param request* param configDTO* param prefix* param extractorCallback* return*/private String createRequestUrl(HttpServletRequest request, RouterDelegateConfigDTO configDTO, String prefix, RouterDelegateExtractor extractorCallback) {String routeUrl configDTO.getRootPath();// 拓展器不为null, 并且有返回结果才使用if (extractorCallback ! null) {String hostUrl extractorCallback.getRequestRootUrl(request, configDTO, prefix);if (hostUrl ! null) routeUrl hostUrl;}String queryString request.getQueryString(); // return routeUrl request.getRequestURI().replace(prefix, ) // (queryString ! null ? ? queryString : );// request.getRequestURI() 包括 server.servlet.context-path// request.getServletPath() 不包括 server.servlet.context-path// http://127.0.0.1/databook-api/graphdb/sj/tianda/openapi/v1/applets?namets// request.getRequestURI() /databook-api/graphdb/sj/tianda/openapi/v1/applets// request.getServletPath() /graphdb/sj/tianda/openapi/v1/appletsString serviceName configDTO.getServiceName();return routeUrl request.getServletPath().replaceFirst(prefix / serviceName, ) (queryString ! null ? ? queryString : );}private RequestEntity createRequestEntity(HttpServletRequest request, String url, RouterDelegateExtractor extractorCallBack) throws URISyntaxException, IOException {String method request.getMethod();HttpMethod httpMethod HttpMethod.resolve(method);HttpHeaders headers parseRequestHeader(request, extractorCallBack);byte[] body parseRequestBody(request, extractorCallBack);return new RequestEntity(body, headers, httpMethod, new URI(url));}private ResponseEntitybyte[] route(HttpServletRequest request, String url, RouterDelegateExtractor extractorCallBack) throws IOException, URISyntaxException {String method request.getMethod();HttpMethod httpMethod HttpMethod.resolve(method);HttpHeaders headers parseRequestHeader(request, extractorCallBack);byte[] body parseRequestBody(request, extractorCallBack);// 设置请求实体HttpEntitybyte[] httpEntity new HttpEntity(body, headers);URI uri new URI(url);return restTemplate.exchange(uri, httpMethod, httpEntity, byte[].class);}private ResponseEntitybyte[] route(RequestEntity requestEntity) {return restTemplate.exchange(requestEntity, byte[].class);}/*** 处理请求头** param request* param extractorCallBack* return*/private HttpHeaders parseRequestHeader(HttpServletRequest request, RouterDelegateExtractor extractorCallBack) {ListString headerNames Collections.list(request.getHeaderNames());HttpHeaders headers new HttpHeaders();for (String headerName : headerNames) {ListString headerValues Collections.list(request.getHeaders(headerName));for (String headerValue : headerValues) {headers.add(headerName, headerValue);}}if (extractorCallBack ! null) {extractorCallBack.parseRequestHeader(request, headers);}// 移除请求头accept-encoding, 不移除会导致响应体转成String时会乱码headers.remove(accept-encoding);return headers;}/*** 处理请求体** param request* param extractorCallBack* return* throws IOException*/private byte[] parseRequestBody(HttpServletRequest request, RouterDelegateExtractor extractorCallBack) throws IOException {// 拓展器不为null, 并且返回的结果也不为null才使用返回结果, 否则使用通用处理逻辑if (extractorCallBack ! null) {byte[] body extractorCallBack.parseRequestBody(request);if (body ! null) return body;}InputStream inputStream request.getInputStream();return StreamUtils.copyToByteArray(inputStream);}}3、暴露接口 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import zsoft.gov.datacenter.biztable.common.router.RouterDelegate;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 路由代理接口*/ RestController RequestMapping public class RouterDelegateController {public final static String DELEGATE_PREFIX /delegate;Autowiredprivate RouterDelegate routerDelegate;/*** 路由代理接口** param serviceName* param request* param response* return*/RequestMapping(value DELEGATE_PREFIX /{serviceName}/**, method {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})public ResponseEntity redirect(PathVariable(serviceName) String serviceName, HttpServletRequest request, HttpServletResponse response) {return routerDelegate.redirect(request, response, DELEGATE_PREFIX, serviceName);}} 4、基础配置 #路由代理配置-网关地址 delegate.config.api.rootPathhttp://192.168.50.43:7612 #路由代理配置-服务名称, 服务名称和服务网关和服务拓展器一一对应, 服务网关和服务拓展器没有则用default代替 delegate.config.api.serviceNamecommon,csdn #路由代理配置-服务网关, 服务名称和服务网关和服务拓展器一一对应, 服务网关和服务拓展器没有则用default代替 delegate.config.api.serviceRootdefault,https://csdn.net #路由代理配置-服务拓展器, 服务名称和服务网关和服务拓展器一一对应, 服务网关和服务拓展器没有则用default代替 delegate.config.api.serviceExtractordefault,csdnBlog
http://www.hkea.cn/news/14559869/

相关文章:

  • 廊坊app网站制作网站建设费用 优帮云
  • 水产网站源码外链群发平台
  • 嘉兴建站模板系统北京做网站比较好的公司
  • 广州网站建站平台WordPress评论ajax提交
  • 吕梁市城乡建设局网站重庆公司网站设计制作
  • 有效的网站建设公遵义在线读者板留言
  • 网站开发技术是仿豆瓣WordPress主题
  • 湘潭做网站 磐石网络怎么才能注册做网站
  • 高稳定性的网站设计制作wordpress可以做电影站
  • 网站页脚模板猎头公司属于什么行业
  • 松滋网站定制网站排名优化原理
  • 织带东莞网站建设技术支持龙岩kk网
  • 网站备案公司上海人才网官网登录
  • 绍兴公司网站建设济南公司做网站
  • 台州网站制作计划职高网页设计与制作
  • 唐山网站提升排名百度大数据平台
  • 《美食天下》网站的建设做网站行业怎么样
  • 网站手机端做app开发ui设计的尺寸
  • 如何安装网站程序网站制作主要公司
  • 买卖域名的网站好个人的网站
  • 企业建站公司平台微信网站设计分析
  • 做读书笔记的网站高校招生网站模板
  • 做网站相关的英文名词中国铁建门户网登录入口
  • 江阴规划建设局网站wordpress广告位代码
  • 中企动力做网站费用wordpress页面 文章页 分类
  • 旅游网站前台模板wordpress成品图
  • 优化网站标题绍兴大公司有哪些
  • 网站开发常用图标 图像设计图纸网站
  • 中国有没有做的好的网站推广app用什么平台比较好
  • seo网站排名优化教程现在最好的营销方式