RestTemplate模拟HTTP请求-跨项目调用接口的工具类
发布日期:2022-02-24 01:06:50 浏览次数:10 分类:技术文章

本文共 10475 字,大约阅读时间需要 34 分钟。

RestTemplate模拟HTTP请求-跨项目调用接口的工具类

自定义RestTemplate工具类:

package io.lili.modules.utils;import cn.hutool.extra.servlet.ServletUtil;import com.alibaba.fastjson.JSON;import com.google.common.collect.Maps;import io.renren.common.constant.Constant;import io.renren.common.exception.RenException;import io.renren.modules.asset.helper.AssertHelper;import lombok.Data;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Value;import org.springframework.http.HttpRequest;import org.springframework.http.client.ClientHttpRequestExecution;import org.springframework.http.client.ClientHttpRequestInterceptor;import org.springframework.http.client.ClientHttpResponse;import org.springframework.stereotype.Component;import org.springframework.web.client.RestTemplate;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.util.DefaultUriBuilderFactory;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import java.io.IOException;import java.io.Serializable;import java.util.*;/** * RestTemplatesUtil * * @author lili */@Component@Slf4jpublic class TargetHRestTemplate {
private RestTemplate restTemplate; private String targetHost; public TargetHRestTemplate(@Value("${target.host}") String targetHost) {
initRestTemplate(); settargetHost(targetHost); } /** * get请求 * @param url 目标接口 * @param params 参数map * @param
* @return */ public
T get(String url, Map params) {
try {
Map tmp = Maps.newHashMap(); if (Objects.nonNull(params)) {
tmp.putAll(params); } url = initUrlWithParams(url, tmp); TargetResult result = restTemplate.getForObject(url, TargetResult.class, tmp); log.debug(result.toString()); AssertHelper.isTrue(result.getCode() == 0, result.getCode()+"-"+result.getMsg()); return (T) result.getData(); } catch (Exception e) {
throw new RenException("所调用的系统不可用(" + e.getMessage() + ")"); } } /** * post请求 * @param url 目标接口 * @param body 请求体内容 * @param params URL中的参数 * @param
* @return */ public
T post(String url, Object body, Map params) {
try {
if (Objects.isNull(body)) {
body = ""; } Map tmp = Maps.newHashMap(); if (Objects.nonNull(params)) {
tmp.putAll(params); } url = initUrlWithParams(url, tmp); TargetResult result = restTemplate.postForObject(url, body, TargetResult.class, tmp); log.debug(result.toString()); AssertHelper.isTrue(result.getCode() == 0, result.getMsg()); return (T) result.getData(); } catch (Exception e) {
throw new RenException("所调用的系统不可用(" + e.getMessage() + ")"); } } /** 转换接口返回的数据类型(结构性的数据类型强转即可: list map) */ public
T parse(Object data, Class
clazz) { //基础类型直接返回 if (clazz.isPrimitive()) { return (T) data; } if (clazz.isAssignableFrom(String.class)) { return (T) data; } //Map直接返回 if (clazz.isAssignableFrom(Map.class)) { return (T) data; } //其他对象、转换返回 return JSON.parseObject(JSON.toJSONString(data), clazz); } public
List
parseList(Object data, Class
clazz) { return JSON.parseArray(JSON.toJSONString(data), clazz); } /** 初始化RestTemplate及拦截 */ public void initRestTemplate() { restTemplate = new RestTemplate(); List
interceptors = new ArrayList<>(); interceptors.add(new TokenInterceptor()); restTemplate.setInterceptors(interceptors); } public void settargetHost(String targetHost) { this.targetHost = targetHost; DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(targetHost); restTemplate.setUriTemplateHandler(uriBuilderFactory); } /** 将map中的参数拼接到url中 */ private String initUrlWithParams(String url, Map params) { Iterator it = params.keySet().iterator(); StringBuffer urlSb = new StringBuffer(url); if (urlSb.indexOf("?") == -1) { urlSb.append("?"); } else { urlSb.append("&"); } while (it.hasNext()) { String k = it.next().toString(); if (urlSb.indexOf("{" + k + "}") == -1) { urlSb.append(k).append("=").append(params.get(k).toString()).append("&"); } } return urlSb.toString(); }}/**定义拦截规则 非必须(我这里必须要登录)很多请求都需要用到相似或者相同的Http Header。如果在每次请求之前都把Header填入HttpEntity/RequestEntity,这样的代码会显得十分冗余。Spring提供了ClientHttpRequestInterceptor接口,可以对请求进行拦截,并在其被发送至服务端之前修改请求或是增强相应的信息*/class TokenInterceptor implements ClientHttpRequestInterceptor { private String getRequestToken(HttpServletRequest httpRequest) { //从header中获取token String token = httpRequest.getHeader("token"); //如果header中不存在token,则从参数中获取token if (StringUtils.isBlank(token)) { token = httpRequest.getParameter("token"); } //如果header中不存在token,则从参数中获取token if (StringUtils.isBlank(token)) { Cookie cookie = ServletUtil.getCookie(httpRequest, "token"); if (Objects.nonNull(cookie)) { token = cookie.getValue(); } } System.out.println("token " + token); return token; } @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); request.getHeaders().set("token", getRequestToken(servletRequestAttributes.getRequest())); return execution.execute(request, body); }}/**我这里目标接口返回的格式是conde码+msg消息+data返回数据 这里可根据自己的数据结构自己定义*/@Dataclass TargetResult implements Serializable { private int code; private String msg; private Object data;}

调用的方法示例:

public class FinanceHelper {
@Autowired private TargetHRestTemplate restTemplate; /** get请求 */ public Map
checkBill(Long sobId, String date) {
Map params = Maps.newHashMap(); params.put("sobId", sobId); params.put("date", date); Map
result = restTemplate.get("/api/finance/checkBill", params); return result; } /** post请求 */ private List
getSobBatch(List
sobIds) {
// 这里的null是因为我的URL请求头不需要请求参数 Object data = restTemplate.post("/api/finance/getSobBatch", sobIds, null); return restTemplate.parseList(data, SobInfo.class);//SobInfo 是我自定义的类 }}

被调用的方法示例:

package io.lili.modules.finance.controller;@RestController@RequestMapping("/api/finance/")public class FinanceAPIController {
@GetMapping("checkBill") public Result checkBill(@RequestParam Map
params) {
String sobId = (String) params.get("sobId"); String date = (String) params.get("date"); //financeSobService是我自定义的类 Map
integerObjectMap = financeSobService.checkBillAssets(Long.valueOf(sobId), date); return new Result().ok(integerObjectMap); } @PostMapping("getSobBatch") public Result financeByAccountTitleId(@RequestBody List
sobList) {
//FinanceSobIdNameVo、financeSobService是我自定义的类 List
sobNameById = financeSobService.getSobNameById(sobList); return new Result().ok(sobNameById); }}

封装相应结果Result类:

package io.lili.common.utils;import io.renren.common.exception.ErrorCode;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import java.io.Serializable;/** * 响应数据 */@ApiModel(value = "响应")public class Result
implements Serializable {
private static final long serialVersionUID = 1L; /** * 编码:0表示成功,其他值表示失败 */ @ApiModelProperty(value = "编码:0表示成功,其他值表示失败") private int code = 0; /** * 消息内容 */ @ApiModelProperty(value = "消息内容") private String msg = "success"; /** * 响应数据 */ @ApiModelProperty(value = "响应数据") private T data; public Result
ok(T data) {
this.setData(data); return this; } public boolean success() {
return code == 0 ? true : false; } public Result
error() {
this.code = ErrorCode.INTERNAL_SERVER_ERROR; this.msg = MessageUtils.getMessage(this.code); return this; } public Result
error(int val2, String str, T data) {
this.code = val2; this.msg = str; this.setData(data); return this; } public Result
error(int code) {
this.code = code; this.msg = MessageUtils.getMessage(this.code); return this; } public Result
error(int code, String msg) { this.code = code; this.msg = msg; return this; } public Result
error(String msg) { this.code = ErrorCode.INTERNAL_SERVER_ERROR; this.msg = msg; return this; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public Result
setMsg(String msg) { this.msg = msg; return this; } public T getData() { return data; } public Result
setData(T data) { this.data = data; return this; }}

链接: .

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

去页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted blockvar foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目 Value
电脑 $1600
手机 $12
导管 $1

设定内容居中、居左、居右

使用:---------:居中

使用:----------居左
使用----------:居右

第一列 第二列 第三列
第一列文本居中 第二列文本居右 第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to-
HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 :

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式.

新的甘特图功能,丰富你的文章

  • 关于 甘特图 语法,参考 ,

UML 图表

可以使用UML图表进行渲染。 . 例如下面产生的一个序列图:

这将产生一个流程图。:

  • 关于 Mermaid 语法,参考 ,

FLowchart流程图

我们依旧会支持flowchart的流程图:

  • 关于 Flowchart流程图 语法,参考 .

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,

继续你的创作。


  1. 注脚的解释

转载地址:https://blog.csdn.net/weixin_45877686/article/details/122103334 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:html+css实现菜单栏缓慢下拉效果
下一篇:深度解析布局利器---Flex布局

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年03月29日 23时46分20秒