You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Java对象转换为以&连接的键值对字符串?

Java对象转无编码&连接键值对的实现方案

以下是几种灵活且高效的实现方式,适配属性动态变更的场景:

1. 使用Apache Commons BeanUtils(推荐,成熟工具类)

借助BeanUtils的describe方法快速获取对象的属性键值对,再自行拼接成目标格式,无需手动维护反射逻辑:

import org.apache.commons.beanutils.BeanUtils;
import java.util.Map;
import java.util.stream.Collectors;

public class ObjectToQueryString {
    public static String convert(Object obj) throws Exception {
        Map<String, String> properties = BeanUtils.describe(obj);
        properties.remove("class"); // 移除默认包含的class属性
        return properties.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));
    }

    // 测试示例
    public static void main(String[] args) throws Exception {
        User user = new User();
        user.setName("John");
        user.setAge(30);
        user.setAddress("12st NW Street");
        user.setCity("New York");
        System.out.println(convert(user));
    }
}

// 你的实体类
class User {
    private String name;
    private int age;
    private String address;
    private String city;

    // 省略getter/setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    public String getAddress() { return address; }
    public void setAddress(String address) { this.address = address; }
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
}

需要引入Apache Commons BeanUtils依赖,Maven坐标如下:

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

2. 基于Spring BeanWrapper(Spring项目首选,无额外依赖)

如果是Spring环境,直接用BeanWrapperImpl获取对象属性信息,无需引入第三方包:

import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;
import java.util.stream.Collectors;

public class ObjectToQueryString {
    public static String convert(Object obj) {
        BeanWrapperImpl wrapper = new BeanWrapperImpl(obj);
        return java.util.Arrays.stream(wrapper.getPropertyDescriptors())
                .filter(pd -> !"class".equals(pd.getName()))
                .map(pd -> {
                    try {
                        Object value = wrapper.getPropertyValue(pd.getName());
                        return pd.getName() + "=" + (value == null ? "" : value.toString());
                    } catch (Exception e) {
                        return "";
                    }
                })
                .filter(s -> !s.isEmpty())
                .collect(Collectors.joining("&"));
    }

    // 测试示例同上述User类
}

3. 优化版自定义反射实现(缓存字段提升性能)

如果不想依赖第三方库,可以自己实现反射,但通过缓存字段信息避免每次遍历类属性,提升重复转换的性能:

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class ObjectToQueryString {
    // 缓存类的字段信息,避免重复反射
    private static final Map<Class<?>, Field[]> FIELD_CACHE = new HashMap<>();

    public static String convert(Object obj) throws IllegalAccessException {
        Class<?> clazz = obj.getClass();
        Field[] fields = FIELD_CACHE.computeIfAbsent(clazz, Class::getDeclaredFields);
        
        return java.util.Arrays.stream(fields)
                .peek(field -> field.setAccessible(true))
                .map(field -> {
                    try {
                        Object value = field.get(obj);
                        return field.getName() + "=" + (value == null ? "" : value.toString());
                    } catch (IllegalAccessException e) {
                        return "";
                    }
                })
                .filter(s -> !s.isEmpty())
                .collect(Collectors.joining("&"));
    }

    // 测试示例同上述User类
}

以上方案都能适配属性动态变更的场景,无需在属性增减时修改转换逻辑。

内容的提问来源于stack exchange,提问作者feco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:35:17