Java 修剪复杂对象中的所有字符串元素

Java 修剪复杂对象中的所有字符串元素,java,Java,我是否可以编写一个通用方法来修剪复杂对象(包含其他对象的对象)中的所有字符串?应该使用java反射api来实现这一点吗?谢谢 我在下面提供了一个样本。然而,在现实中,对象中可能有多个对象。每个对象可能包含一个字符串集合或可能包含字符串的其他对象集合。是否有一种方法可以修剪字符串-直接使用对象修剪字符串和集合中的字符串 public class School{ private List<Course> courses; private List<Student>

我是否可以编写一个通用方法来修剪复杂对象(包含其他对象的对象)中的所有字符串?应该使用java反射api来实现这一点吗?谢谢

我在下面提供了一个样本。然而,在现实中,对象中可能有多个对象。每个对象可能包含一个字符串集合或可能包含字符串的其他对象集合。是否有一种方法可以修剪字符串-直接使用对象修剪字符串和集合中的字符串

public class School{
   private List<Course> courses;
   private List<Student> students;       
   // Getters and Setters
}

public class Course{
   private String name;
   private String xxx;
   private String yyy;
   private List<String> zzzList;
}

public class Student{
   private Map<String,String> xxx;
   private List<Course> courseList;
}
公立学校{
私人名单课程;
私人名单学生;
//接球手和接球手
}
公共课{
私有字符串名称;
私有字符串xxx;
私有字符串yyy;
私人名单;
}
公立班学生{
私人地图xxx;
私人名单课程专家;
}

是的,您可以很容易地通过反射来实现这一点。只需检查该字段是否为字符串的
instanceof

具体方法取决于对象结构

if (yourObject instanceof String){
    yourObject = yourObject.trim();
}

希望有帮助:)

是的,反思才是出路。基本上,您需要:

  • 获取顶级对象的类(使用[object].getClass())

  • 获取对象的所有字段(使用clazz.getFields()-注意,它仅适用于公共字段)

  • 检查字段是否为字符串(要么获取field.getType()并检查它是否为字符串,要么执行field.get(对象)和instanceof String)

  • 如果是这种情况,请使用field.set([您的对象],[修剪的字符串])将对象中的字符串替换为修剪的字符串

  • 如果字段是对象而不是字符串,则递归调用方法

那就行了

----刚刚看到你的更新

修剪集合中的字符串将更加棘手,因为字符串不会作为集合的公共字段公开(例如列表)

您将需要更聪明的东西,它将检查对象是否是List、Map等的实例。。。(或派生类!)。 主要问题还在于java泛型是通过在编译类型上擦除类型来完成的。因此,您无法知道您的字段是List[String]或List[Integer]或其他内容。每个列表[?]都成为列表

您仍然可以尝试这样做:

  • 如果字段类型为列表
  • 遍历列表值
  • 如果某个值是instanceof String,则必须将其从列表中删除,并在适当位置插入修剪后的版本
  • 如果一个值是一个对象,那么您可以使用您的方法再次递归
现实生活中的样本不是很有趣,但图书馆方面可能更有趣。 尽管还有很长的路要走

private T toTrim(T T){
/*********************************************************************************************
 * Trim first level children of string type in this object
 * @param obj which all string properties to be trimmed
 *********************************************************************************************/
public static void trimAll(final Object obj)
throws LocalException
{
    if (obj==null) return;

    final Class    c           = obj.getClass();
    final Method[] methods     = c.getMethods();
    final Class[]  SETTER_ARGS = new Class[]{String.class};
    final Object[] SETTER_VAL  = new Object[1];
    final String   SET         = "set";
    final String   GET         = "get";
    final String   SPACE       = "\u0020";
    final String   TAB         = "\t";

    for (final Method m:methods)
    {
        try
        {
            final String name=m.getName();
            if (
                name.length()>GET.length()
             && name.indexOf(GET)==0
             && m.getReturnType().equals(String.class)
             && m.getParameterTypes().length==0)
            {
                final String v = (String)m.invoke(obj);
                if (v!=null && (v.contains(SPACE) || v.contains(TAB)) )
                {
                    final Method setter=c.getMethod(SET+name.substring(3),SETTER_ARGS);
                    if (setter!=null)
                    {
                        SETTER_VAL[0]=v.trim();
                        setter.invoke(obj,SETTER_VAL);
                    }
                }
            }
        }
        catch (final Throwable e)
        {
            throw new LocalException(LocalException.EC_GENERAL_EXCEPTION,e);
        }
    }
}
Field[]fields=t.getClass().getFields(); 用于(字段:字段){ 试一试{ if(field.get(t)instanceof String){ 对象o=字段get(t); 字符串s=(字符串)o; set(t,s.trim().toUpperCase()); } }捕获(非法访问例外e){ log.info(“错误转换字段”+field.getName()); } } 返回t; }
我们还可以使用Jackson序列化然后反序列化对象。在反序列化时,我们可以使用自定义反序列化程序来修剪所有字符串值

创建如下所示的反序列化程序:

public class TrimStringToNullDeserializer extends JsonDeserializer<String> {

@Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
        throws IOException {
    String value = jsonParser.getValueAsString();

    if (isNull(value)) {
        return null;
    }
    value = value.trim();
    if (value.length() == 0) {
        value = null;
    }
    return value;
}

我举了一个工作示例

问题太模糊了。这当然是可能的,是的。应该如何做取决于对象结构。嗨-更新了我原来帖子中的示例对象结构。非常感谢huelbois!我可能还有很多其他的收藏也在使用。正如你提到的,还有很长的路要走!别忘了接受你问题的最佳答案……;)欢迎来到SO!虽然你发布的代码可能会回答这个问题,但如果你提供一些解释,帮助OP和这个问题的未来观众理解它的作用,那就更好了。
public class TrimStringToNullDeserializer extends JsonDeserializer<String> {

@Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
        throws IOException {
    String value = jsonParser.getValueAsString();

    if (isNull(value)) {
        return null;
    }
    value = value.trim();
    if (value.length() == 0) {
        value = null;
    }
    return value;
}
public class TrimStringToNullConfiguration {

private ObjectMapper objectMapper;

public Client trimToNull(Client inputClient) throws JsonProcessingException {
    return getObjectMapper().readValue(getObjectMapper().writeValueAsString(inputClient), Client.class);
}

private ObjectMapper getObjectMapper() {
    if (isNull(objectMapper)) {
        objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(String.class, new TrimStringToNullDeserializer());
        objectMapper.registerModule(module);
    }
    return objectMapper;
}