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

邢台网站建设制作资讯类网站建设方案书

邢台网站建设制作,资讯类网站建设方案书,唐山做网站公司,厦门企业制作网站一、前言 最近带着两个兄弟做支付宝小程序后端相关的开发#xff0c;小程序首页涉及到很多查询的服务。小程序后端服务在我司属于互联网域#xff0c;相关的查询服务已经在核心域存在了#xff0c;查询这块所要做的工作就是做接口中转。参考了微信小程序的代码#xff0c;发… 一、前言   最近带着两个兄弟做支付宝小程序后端相关的开发小程序首页涉及到很多查询的服务。小程序后端服务在我司属于互联网域相关的查询服务已经在核心域存在了查询这块所要做的工作就是做接口中转。参考了微信小程序的代码发现他们要么新写一个接口调用要么新写一个接口包裹多个接口调用。这种方式不容易扩展。由于开发周期比较理想所以决定设计一个接口中转器。 二、接口中转器整体设计      三、接口中转器核心Bean Bean public SimpleUrlHandlerMapping directUrlHandlerMapping(Autowired RequestMappingHandlerAdapter handlerAdapter, ObjectProviderListIDirectUrlProcessor directUrlProcessorsProvider) {ListIDirectUrlProcessor directUrlProcessors directUrlProcessorsProvider.getIfAvailable();Assert.notEmpty(directUrlProcessors, 接口直达解析器IDirectUrlProcessor列表不能为空);SimpleUrlHandlerMapping mapping new SimpleUrlHandlerMapping();MapString, Controller urlMappings Maps.newHashMap();urlMappings.put(/alipay-applet/direct/**, new AbstractController() {Overrideprotected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {for (IDirectUrlProcessor directUrlProcessor : directUrlProcessors) {if (directUrlProcessor.support(request)) {String accept request.getHeader(Accept);request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Sets.newHashSet(MediaType.APPLICATION_JSON_UTF8));if (StringUtils.isNotBlank(accept) !accept.contains(MediaType.ALL_VALUE)) {request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Sets.newHashSet(Arrays.stream(accept.split(,)).map(value - MediaType.parseMediaType(value.trim())).toArray(size - new MediaType[size])));}HandlerMethod handlerMethod new HandlerMethod(directUrlProcessor, ReflectionUtils.findMethod(IDirectUrlProcessor.class, handle, HttpServletRequest.class));return handlerAdapter.handle(request, response, handlerMethod);}}throw new RuntimeException(未找到具体的接口直达处理器...);}});mapping.setUrlMap(urlMappings);mapping.setOrder(Ordered.HIGHEST_PRECEDENCE 1);return mapping; }   关于核心Bean的示意如下。 使用SimpleUrlHandlerMapping 来过滤请求路径中包含/alipay-applet/direct/**的请求认为这样的请求需要做接口中转。针对中转的请求使用一个Controller进行处理即AbstractController的一个实例并重写其handleRequestInternal。对于不同的中转请求找到对应的中转处理器然后创建相应的HandlerMethod 再借助SpringMvc的RequestMappingHandlerAdapter调用具体中转处理器接口以及返回值的处理。  为什么要使用RequestMappingHandlerAdapter因为中转处理器的返回值类型统一为ReponseEntityString想借助RequestMappingHandlerAdapter中的HandlerMethodReturnValueHandler来处理返回结果。 request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Sets.newHashSet(MediaType.APPLICATION_JSON_UTF8));   为什么会有这段代码这是HandlerMethodReturnValueHandler调用的MessageConverter需要的代码如下。      我手动设置的原因是因为RequestMappingHandlerAdapter是和RequestMappingHandlerMapping配合使用的RequestMappingHandlerMapping会在request的attribute中设置RequestMappingInfo.producesCondition.getProducibleMediaTypes()这个值。具体参考代码如下。 org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#handleMatch org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#createRequestMappingInfo 四、请求转发RestTempate配置 Bean public RestTemplate directRestTemplate() throws Exception {try {RestTemplate restTemplate new RestTemplate(clientHttpRequestFactory());restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {Overridepublic void handleError(ClientHttpResponse response) throws IOException {throw new RestClientResponseException(response.getStatusCode().value() response.getStatusText(),response.getStatusCode().value(), response.getStatusText(), response.getHeaders(), getResponseBody(response), getCharset(response));}protected byte[] getResponseBody(ClientHttpResponse response) {try {InputStream responseBody response.getBody();if (responseBody ! null) {return FileCopyUtils.copyToByteArray(responseBody);}} catch (IOException ex) {// ignore}return new byte[0];}protected Charset getCharset(ClientHttpResponse response) {HttpHeaders headers response.getHeaders();MediaType contentType headers.getContentType();return contentType ! null ? contentType.getCharset() : null;}});// 修改StringHttpMessageConverter内容转换器restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));return restTemplate;} catch (Exception e) {throw new Exception(网络异常或请求错误., e);} }/*** 接受未信任的请求** return* throws KeyStoreException* throws NoSuchAlgorithmException* throws KeyManagementException*/ Bean public ClientHttpRequestFactory clientHttpRequestFactory()throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {HttpClientBuilder httpClientBuilder HttpClientBuilder.create();SSLContext sslContext new SSLContextBuilder().loadTrustMaterial(null, (arg0, arg1) - true).build();httpClientBuilder.setSSLContext(sslContext).setMaxConnTotal(MAX_CONNECTION_TOTAL).setMaxConnPerRoute(ROUTE_MAX_COUNT).evictIdleConnections(CONNECTION_IDLE_TIME_OUT, TimeUnit.MILLISECONDS);httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(RETRY_COUNT, true));httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());CloseableHttpClient client httpClientBuilder.build();HttpComponentsClientHttpRequestFactory clientHttpRequestFactory new HttpComponentsClientHttpRequestFactory(client);clientHttpRequestFactory.setConnectTimeout(CONNECTION_TIME_OUT);clientHttpRequestFactory.setReadTimeout(READ_TIME_OUT);clientHttpRequestFactory.setConnectionRequestTimeout(CONNECTION_REQUEST_TIME_OUT);clientHttpRequestFactory.setBufferRequestBody(false);return clientHttpRequestFactory; }   关于RestTemplte配置的示意如下。 设置RestTemplte统一异常处理器统一返回RestClientResponseException。设置RestTemplte HttpRequestFactory连接池工厂HttpClientBuilder的build方法会创建PoolingHttpClientConnectionManager。设置RestTemplte StringHttpMessageConverter的编码格式为UTF-8。设置最大连接数、路由并发数、重试次数、连接超时、数据超时、连接等待、连接空闲超时等参数。五、接口中转处理器设计    考虑到针对不同类型的接口直达请求会对应不同的接口中转处理器设计原则一定要明确open-close。平时也阅读spingmvc源码很喜欢其中消息转换器和参数解析器的设计模式策略模板方法。仔细想想接口中转处理器的设计也可以借鉴一下。   接口中转处理器接口类 public interface IDirectUrlProcessor {/*** 接口直达策略方法* 处理接口直达请求* */ResponseEntityString handle(HttpServletRequest request) throws Exception;/*** 处理器是否支持当前直达请求* */boolean support(HttpServletRequest request); }   接口定义了子类需要根据不同的策略实现的两个方法。   接口中转处理器抽象类 public abstract class AbstractIDirectUrlProcessor implements IDirectUrlProcessor {private static Logger LOGGER LoggerFactory.getLogger(AbstractIDirectUrlProcessor.class);Autowiredprivate RestTemplate directRestTemplate;/*** 接口直达模板方法* */protected ResponseEntityString handleRestfulCore(HttpServletRequest request, URI uri, String userId) throws Exception {HttpMethod method HttpMethod.resolve(request.getMethod());Object body;if (method HttpMethod.GET) {body null;} else {body new BufferedReader(new InputStreamReader(request.getInputStream())).lines().collect(Collectors.joining());// post/formif (StringUtils.isBlank((String) body)) {MultiValueMapString, String params new LinkedMultiValueMap();if (!CollectionUtils.isEmpty(request.getParameterMap())) {request.getParameterMap().forEach((paramName, paramValues) - Arrays.stream(paramValues).forEach(paramValue - params.add(paramName, paramValue)));body params;}}}HttpHeaders headers new HttpHeaders();CollectionUtils.toIterator(request.getHeaderNames()).forEachRemaining(headerName - CollectionUtils.toIterator(request.getHeaders(headerName)).forEachRemaining(headerValue - headers.add(headerName, headerValue)));RequestEntity directRequest new RequestEntity(body, headers, method, uri);try {LOGGER.info(String.format(接口直达UserId %s, RequestEntity %s, userId, directRequest));ResponseEntityString directResponse directRestTemplate.exchange(directRequest, String.class);LOGGER.info(String.format(接口直达UserId %s, URL %s, ResponseEntity %s, userId, directRequest.getUrl(), directResponse));return ResponseEntity.ok(directResponse.getBody());} catch (RestClientResponseException e) {LOGGER.error(restapi 内部异常, e);return ResponseEntity.status(e.getRawStatusCode()).body(e.getResponseBodyAsString());} catch (Exception e) {LOGGER.error(restapi 内部异常未知错误..., e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(restapi 内部异常未知错误...);}} }   抽象类中带有接口直达模板方法子类可以直接调用完成请求的转发。   接口中转处理器具体实现类 /*** 自助服务直达查询*/ Component public class SelfServiceIDirectUrlProcessor extends AbstractIDirectUrlProcessor {private static final String CONDITION_PATH /alipay-applet/direct;Reference(group wmhcomplexmsgcenter)private IAlipayAppletUserInfoSV alipayAppletUserInfoSV;private void buildQueryAndPath(UriComponentsBuilder uriComponentsBuilder, AlipayAppletUser userInfo) {uriComponentsBuilder.path(/ userInfo.getTelephone()).queryParam(channel, 10008).queryParam(uid, userInfo.getUserId()).queryParam(provinceid, userInfo.getProvinceCode());}public ResponseEntityString handle(HttpServletRequest request) throws Exception {String userId JwtUtils.resolveUserId();AlipayAppletUser userInfo alipayAppletUserInfoSV.queryUserInfo(userId);UriComponentsBuilder uriComponentsBuilder UriComponentsBuilder.fromHttpUrl(AppletConstants.ISERVICE_BASEURL request.getServletPath().replace(CONDITION_PATH, StringUtils.EMPTY));if (StringUtils.isNotBlank(request.getQueryString())) {uriComponentsBuilder.query(request.getQueryString());}this.buildQueryAndPath(uriComponentsBuilder, userInfo);String url uriComponentsBuilder.build().toUriString();URI uri URI.create(url);return handleRestfulCore(request, uri, userId);}Overridepublic boolean support(HttpServletRequest request) {return request.getServletPath().contains(CONDITION_PATH);} }   接口中转处理器具体实现类需要根据请求的URL判断是否支持处理当前请求如果中转请求中带有敏感信息如手机号需要特殊处理UriComponentsBuilder 是一个不错的选择呦。 六、总结   接口中转器扩展方便只要按照如上方式根据不同类型的request实现具体的接口中转处理器就可以了。另外就是接口文档了有了接口中转处理器只需要改一下真实服务的接口文档就可以。比如真实服务的请求地址是http://172.17.20.92:28000/XXX/business/points/手机号信息只需要改成http://172.17.20.92:28000/YYY/alipay-applet/direct/business/points。【手机号信息是敏感信息需要后端从会话信息中获取】。还有不要问我为啥要花时间设计这个东西第一领导同意了第二开发周期理想第三我喜欢 转载于:https://www.cnblogs.com/hujunzheng/p/10250403.html
http://www.sadfv.cn/news/419629/

相关文章:

  • 做美食的网站可以放些小图片好口碑关键词优化
  • 个人备案网站建设方案书微商营销
  • 西宁做腋臭哪里北大DE网站微信小商店开店流程
  • 苏州吴中长桥网站建设关于网站建设的文章
  • 企业网站开发韵茵新浪 博客可以做网站优化吗
  • 安徽省建设厅执业资格注册中心网站已经备案的网站新增ip怎么做
  • 数据分析网站开发设计师设计软件
  • paypal可做网站公众号运营岗位职责
  • 网站建设免费的服务器网站开发用什么软件开发
  • 北京网站建设收费福建住房与城乡建设网站
  • 网站如何吸引wordpress使用什么数据库
  • 郑州专业网站建设公司详情wordpress淘宝模板
  • 学校网站模版简述电子商务网站的建设步骤
  • wordpress软件站模板企?I网站建站 ?V州 ??l
  • 北京微信网站开发报价企业网站建设过程
  • 网站建设的主要内容有哪些网站可以免费推广
  • 去公司叫自己做网站不会做阿里云centos7 搭建wordpress
  • 泰安市住房和城乡建设部网站网站源码下载地址是什么
  • 网站开发api平台sever2012做网站
  • 网站用微信登录 要怎么做新手学网络运营要多久
  • 潍坊市网站制作贵州省住房和城乡建设厅证件查询
  • 网站开发速成班海北wap网站建设
  • 南京华璋建设网站免费注册163免费邮箱个人
  • 南通网站排名方法本溪seo优化
  • 青岛高创网站建设cms视频系统大全
  • 易语言可以建设网站吗网站设计策略
  • 美容茌哪个网站做宣传好前端开发人员怎么做网站
  • 做网站的商家怎么赚取流量费做网站如何突出网站特色
  • 网上做一道题2元的网站聊城网站建设 推广聊城博达
  • 网站建设公司好做吗公司邮箱怎么查询