我可以编写一个通用方法来修剪复杂对象(包含其他对象的对象)中的所有字符串吗?应该用java反射api来实现这个吗?谢谢。
我在下面提供了一个示例。但实际上,对象中可能存在多个对象。每个对象可能包含一个String集合或其他可能包含String的对象的集合。有没有办法修剪字符串 - 直接使用对象和集合中的字符串。
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;
}
答案 0 :(得分:6)
是的,反思就是这样。基本上,你需要:
获取顶级对象的类(使用[object] .getClass())
获取对象的所有字段(使用clazz.getFields() - 注意,它只适用于公共字段)
检查字段是否为String(获取field.getType()并检查它是否为字符串,或者执行field.get(对象)和instanceof String)
如果是这种情况,请使用field.set([您的对象],[修剪后的字符串])
如果字段是对象但不是字符串,则以递归方式调用方法
这样就可以了。
----刚看到你的更新
修剪集合中的字符串会比较棘手,因为字符串不会作为集合的公共字段公开(例如List)。
你需要一些更聪明的东西,它会检查一个对象是否是List,Map或其他......的实例(或派生类!)。 主要问题是java泛型是在编译类型下使用擦除类型完成的。所以你不能知道你的字段是List [String]或List [Integer]或者其他什么。每个列表[?]都成为列表。
你仍然可以尝试这样做:
在现实生活中的样本不是很有趣,但在图书馆方面可能更多。 很长的路要走!
答案 1 :(得分:2)
是的,你可以很容易地用反射做到这一点。只需检查字段是否为instanceof String
。
确切的方法取决于您的对象结构。
答案 2 :(得分:1)
/*********************************************************************************************
* 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);
}
}
}
答案 3 :(得分:1)
我们还可以使用Jackson进行序列化,然后反序列化对象。反序列化时,我们可以使用自定义反序列化器修剪所有String值。
创建这样的反序列化器:
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;
}
然后我们可以使用Jackson修剪所有值:
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;
}
我已经提供了一个有效的示例over here.
答案 4 :(得分:0)
private <T> T toTrim(T t) {
Field[] fields = t.getClass().getFields();
for (Field field : fields) {
try {
if (field.get(t) instanceof String) {
Object o = field.get(t);
String s = (String) o;
field.set(t, s.trim().toUpperCase());
}
} catch (IllegalAccessException e) {
log.info("Error converting field "+ field.getName() );
}
}
return t;
}
答案 5 :(得分:-1)
if (yourObject instanceof String){
yourObject = yourObject.trim();
}
希望有所帮助:)