已解决: java 使用feign远程调用接口,响应的list集合不能使用,无法转换为map

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.fangwenjun.common.To.SkuHasStockVo
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320) ~[na:1.8.0_191]
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) ~[na:1.8.0_191]
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[na:1.8.0_191]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_191]

原因:

服务提供者在返回数据时, 返回的结果为list集合, 接口使用@ResponseBody 注解响应, 会把list集合转换为json格式响应,默认使用的是jackjson,.
在服务消费者接收响应时,使用的应该是另一种json格式,导致接收的数据转换为list时不能使用,遍历或者转换会报错,

解决方法:

使用fastjson 工具类把集合转换为字符串格式,然后在转换成集合就能使用了.
在这里插入图片描述

参考博客链接:
https://blog.csdn.net/weixin_44142032/article/details/105682967

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Java和druid解析sql,并通过feign接口查询到的表元数据,替换包含left join的insert into table select sql语句中的*的代码示例: ```java import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.util.JdbcConstants; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.common.base.Joiner; import feign.Feign; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Slf4j public class SqlParserUtils { /** * 解析insert into table select语句中的表名 */ public static String parseTableName(String sql) { List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); SQLInsertStatement insertStmt = (SQLInsertStatement) stmtList.get(0); SQLSelectStatement selectStmt = (SQLSelectStatement) insertStmt.getQuery().getQuery(); SQLSelect sqlSelect = selectStmt.getSelect(); SQLSelectQueryBlock sqlSelectQuery = (SQLSelectQueryBlock) sqlSelect.getQuery(); SQLTableSource tableSource = sqlSelectQuery.getFrom(); if (tableSource instanceof SQLExprTableSource) { return ((SQLExprTableSource) tableSource).getName().getSimpleName(); } else if (tableSource instanceof SQLJoinTableSource) { SQLJoinTableSource joinSource = (SQLJoinTableSource) tableSource; SQLTableSource left = joinSource.getLeft(); if (left instanceof SQLExprTableSource) { return ((SQLExprTableSource) left).getName().getSimpleName(); } } throw new IllegalArgumentException("无法解析的SQL语句"); } /** * 解析insert into table select语句中的列名 */ public static List<String> parseColumnNames(String sql) { List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); SQLInsertStatement insertStmt = (SQLInsertStatement) stmtList.get(0); SQLSelectStatement selectStmt = (SQLSelectStatement) insertStmt.getQuery().getQuery(); SQLSelect sqlSelect = selectStmt.getSelect(); SQLSelectQueryBlock sqlSelectQuery = (SQLSelectQueryBlock) sqlSelect.getQuery(); List<SQLSelectItem> selectList = sqlSelectQuery.getSelectList(); List<String> columnNames = new ArrayList<>(); for (SQLSelectItem selectItem : selectList) { SQLExpr expr = selectItem.getExpr(); if (expr instanceof SQLIdentifierExpr) { columnNames.add(((SQLIdentifierExpr) expr).getName()); } } return columnNames; } /** * 替换insert into table select语句中的*为实际列名 */ public static String replaceAsterisk(String sql, List<String> columnNames) { SQLSelectParser parser = new MySqlSelectParser(sql); SQLSelect select = parser.select(); SQLSelectQueryBlock query = (SQLSelectQueryBlock) select.getQuery(); List<SQLSelectItem> selectList = query.getSelectList(); if (!CollectionUtils.isEmpty(selectList)) { for (int i = 0; i < selectList.size(); i++) { SQLSelectItem selectItem = selectList.get(i); SQLExpr expr = selectItem.getExpr(); if (expr instanceof SQLAllColumnExpr) { selectList.remove(i); for (String columnName : columnNames) { SQLSelectItem newSelectItem = new SQLSelectItem(new SQLIdentifierExpr(columnName)); selectList.add(i, newSelectItem); i++; } break; } } } return SQLUtils.toMySqlString(select); } /** * 查询表元数据 */ public static JSONObject getTableMetadata(String tableName, String metadataServiceUrl) { Feign.Builder builder = Feign.builder() .encoder(new GsonEncoder()) .decoder(new GsonDecoder()) .logger(new Slf4jLogger(SqlParserUtils.class)) .client(new OkHttpClient()); MetadataServiceClient client = builder.target(MetadataServiceClient.class, metadataServiceUrl); Map<String, Object> result = client.getTableMetadata(tableName); return JSON.parseObject(JSON.toJSONString(result)); } /** * 替换insert into table select语句中的*为实际列名,并获取列的类型信息 */ public static String replaceAsteriskAndGetType(String sql, String metadataServiceUrl) { String tableName = parseTableName(sql); List<String> columnNames = parseColumnNames(sql); JSONObject tableMetadata = getTableMetadata(tableName, metadataServiceUrl); List<JSONObject> columns = tableMetadata.getJSONArray("columns").toJavaList(JSONObject.class); List<String> columnTypes = columns.stream().filter(column -> columnNames.contains(column.getString("name"))) .map(column -> column.getString("type")).collect(Collectors.toList()); String replacedSql = replaceAsterisk(sql, columnNames); String columnTypesStr = Joiner.on(",").join(columnTypes); return String.format("%s/*{%s}*/", replacedSql, columnTypesStr); } } ``` 其中,MetadataServiceClient为通过Feign实现的调用元数据服务接口的客户端,代码示例如下: ```java import feign.RequestLine; import java.util.Map; public interface MetadataServiceClient { @RequestLine("GET /metadata/tables/{tableName}") Map<String, Object> getTableMetadata(String tableName); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值