Java中接口返回参数按照请求参数进行排序

Java 中返回参数按照请求参数进行排序

在开发接口的时候,有时候我们会遇到这样的场景,前端传来的参数是一个列表,我们通过这些参数在数据库中查询出一个列表,但是在数据库中查询出来的这个列表和前端传来的参数的顺序不一致。

比方说我们的数据库中 user 表有以下几条数据:

iduidname
1user_003法半夏
2user_001蜜远志
3user_002麦冬
4user_004茵陈

我们需要 通过前端传来的参数 uid 列表 查询 其中的数据,然后返回给前端,但是前端传来的 uid 列表是 [“user_001”, “user_002”, “user_003” ,“user_004”] ,这时候,我们通过

SELECT uid,`name` from user where uid 
IN('user_001','user_002','user_003','user_004');

查询出来的结果是这样的:

iduidname
1user_003法半夏
2user_001蜜远志
3user_002麦冬
4user_004茵陈
即: 返回到前端的数据是这样的
[
	{"name":"法半夏","uid":"user_003"},
	{"name":"蜜远志","uid":"user_001"},
	{"name":"麦冬","uid":"user_002"},
	{"name":"茵陈","uid":"user_004"}
]

可以看到传入的参数列表和返回的列表 uid 并不是对应的。

我们希望的是返回 :
[
	{"name":"蜜远志","uid":"user_001"},
	{"name":"麦冬","uid":"user_002"},
	{"name":"法半夏","uid":"user_003"},
	{"name":"茵陈","uid":"user_004"}
]

为了解决这个问题,有多种方法,比方说在mybatis 中 先 使用 foreach 入参列表 再left join user 表, 但 这样的缺点是当参数列表较长的时候sql 语句可能很长,sql 语句解析可能会比较慢,占用网络带宽可能较大,总而言之就是可能存在 bug;

综上所述,我们采用在 java 代码中实现排序

不想打字了,直接上代码
排序工具类:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author: XiaTian
 * @create-time 18:22 2021/11/14
 */
public class OrderUtil {
    private static Logger logger = LoggerFactory.getLogger(OrderUtil.class);

    /**
     * 排序操作
     * @param originList 数据库中查询出来的的列表,需要排序操作
     * @param orderList 前端传来的参数列表
     * @param orderField 需要排序的字段, 如: uid
     * @param <T> 泛型
     * @return
     */
    public static <T> List<T> order(List<T> originList,
                                    List<String> orderList,
                                    final String orderField){
        if (CollectionUtils.isEmpty(originList)){
            logger.info("入参集合为空");
            return originList;
        }
        Map<String,T> tempMap = new HashMap<>();
        Field declaredField;
        List<T> rtnList = new ArrayList<>();
        try {
            declaredField = originList.get(0).getClass().getDeclaredField(orderField);
            declaredField.setAccessible(true);
            for (T ele : originList){
                String value = declaredField.get(ele).toString();
                tempMap.put(value,ele);
            }
            for (String code : orderList){
                rtnList.add(tempMap.get(code));
            }
        } catch (NoSuchFieldException e) {
           logger.warn("没用指定字段[{}]",orderField);
        } catch (IllegalAccessException e) {
            logger.warn("访问字段非法,请检查字段[{}]权限",orderField);
        }
        return rtnList;
    }

    public static void main(String[] args) {
        List<String> orderList = Arrays.asList("user_001","user_002","user_003","user_004");
        List<User> userList = new ArrayList<>();
        userList.add(new User(1,"user_003","法半夏"));
        userList.add(new User(2,"user_001","蜜远志"));
        userList.add(new User(3,"user_002","麦冬"));
        userList.add(new User(4,"user_004","茵陈"));
        List<User> orderedUsers = OrderUtil.order(userList, orderList, "uid");
        System.out.println(orderedUsers);
    }
}

user 类

package com.xhw.product.outman.util;

import lombok.Data;

/**
 * @author: XiaTian
 * @create-time 18:37 2021/11/14
 */
@Data
public class User {
    private int id;
    private String uid;
    private String name;

    public User(int id, String uid, String name) {
        this.id = id;
        this.uid = uid;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", uid='" + uid + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个Java请求签名校验逻辑的示例代码,它考虑了url的params和body的json,参数按照特定顺序排序: ```java import java.util.*; public class RequestSignValidator { private static final String SECRET_KEY = "your_secret_key"; private static final String SIGNATURE_PARAM_NAME = "signature"; public static boolean isValidRequest(Map<String, String> params, String bodyJson, String signature) { // 按照参数名升序排序 TreeMap<String, String> sortedParams = new TreeMap<>(params); // 将bodyJson作为参数放入Map sortedParams.put("body", bodyJson); // 拼接参数键值对为字符串 StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> entry : sortedParams.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } sb.append(SECRET_KEY); // 计算签名并与入的签名比较 String calculatedSignature = DigestUtils.md5Hex(sb.toString()).toUpperCase(); return calculatedSignature.equals(signature); } } ``` 其,`SECRET_KEY`是你的密钥,`SIGNATURE_PARAM_NAME`是签名参数的名称。`isValidRequest`方法接收三个参数:`params`是url的params,以Map形式入;`bodyJson`是body的json字符串;`signature`是入的签名值。方法内部先将参数按照参数名升序排序,并将`bodyJson`作为参数放入Map,然后拼接成字符串。最后使用MD5算法计算字符串的摘要,并将结果转换成大写字符串,与入的签名值比较,如果相等则返回true,否则返回false。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值