如何将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
相关产品推荐
相关产品推荐

