这是将servlet请求参数映射到java类的最佳方法?

时间:2011-04-19 15:08:43

标签: java reflection servlets mapping

  

可能重复:
  Easy way of populating Javabeans based on request parameters

嗨,

我有一个带有一组搜索参数的Java对象,某事。喜欢

public class SearchRequest {

private String customerName;
private String city;
...
}

此请求必须由服务请求填写。

但不是像

那样编写代码

...

SearchRequest searchRequest = new SearchRequest();

if (request.getParameter("customerName") != null)
{ 
    searchRequest.setCustomerName(request.getParameter("customerName"));
}
if (request.getParameter("city") != null)
{ 
    searchRequest.setCity(request.getParameter("city"));
}

... 我正在寻找一种更通用的方式。

我正在检查映射工具Dozer,但没有找到一种很好的方法来处理这种映射。

现在我认为反思将是一种选择。 这是真的? 如果有的话,是否有人有一个代码片段,如何用反射来完成?

1 个答案:

答案 0 :(得分:2)

我认罪:

public void save(HttpServletRequest req, Object obj) {
    Set<String> names = new HashSet<String>();
    @SuppressWarnings("unchecked")
    Enumeration<String> enm = req.getParameterNames();
    while (enm.hasMoreElements()) {
        names.add(enm.nextElement());
    }
    Class clazz = obj.getClass();
    while (clazz != Object.class && !names.isEmpty()) {
        for (Field f: clazz.getDeclaredFields()) {
            if (!Modifier.isTransient(f.getModifiers())) {
                String name = f.getName();
                if (names.contains(name)) {
                    try {
                        names.remove(name);
                        f.setAccessible(true);
                        Object val = convertValue(req, f.getType(),
                                name);
                        f.set(obj, val);
                    } catch (ParseException ex) {
                        LOG.error("Error assigning field", ex);
                    } catch (IllegalAccessException ex) {
                        LOG.error("Error assigning field", ex);
                    }
                }
            }
        }
        clazz = clazz.getSuperclass();
    }
}

private Object convertValue(HttpServletRequest req, Class<?> type,
        String name) throws ParseException {
    if (type.isArray()) {
        Class<?> elemType = type.getComponentType();
        String strings[] = req.getParameterValues(name);
        if (strings == null || strings.length == 0) {
            return new Object[0];
        }
        Object array = Array.newInstance(elemType, strings.length);
        for (int i = 0; i < strings.length; ++i) {
            Object val = parse(elemType, strings[i]);
            Array.set(array, i, val);
        }
        return array;
    } else {
        String s = req.getParameter(name);
        if (s == null) {
            return null;
        }
        return parse(type, s);
    }
}

public static Object parse(Class<?> type, String value)
        throws ParseException {
    if (type == String.class) {
        return value;
    } else if (value == null || value.length() == 0) {
        return null;
    } else if (Enum.class.isAssignableFrom(type)) {
        @SuppressWarnings("unchecked")
        Object result = Enum.valueOf((Class<? extends Enum>)type, value);
        return result;
    } else if (type == boolean.class || type == Boolean.class) {
        return "true".equals(value);
    } else if (type == byte.class || type == Byte.class) {
        return Byte.valueOf(value);
    } else if (type == short.class || type == Short.class) {
        return Short.valueOf(value);
    } else if (type == int.class || type == Integer.class) {
        return Integer.valueOf(value);
    } else if (type == long.class || type == Long.class) {
        return Long.valueOf(value);
    } else if (type == float.class || type == Float.class) {
        return Float.valueOf(value);
    } else if (type == double.class || type == Double.class) {
        return Double.valueOf(value);
    } else if (type == Date.class) {
            return new SimpleDateFormat("dd/MM/yyyy").parse(value);
    } else if (type == BigDecimal.class) {
        DecimalFormat format = getDecimalFormat("0.00");
        return format.parse(value);
    } else {
        throw new RuntimeException("Cannot convert value of type " + type);
    }
}

private static DecimalFormat getDecimalFormat(String pattern) {
    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
    symbols.setDecimalSeparator('.');
    DecimalFormat format = new DecimalFormat(pattern);
    format.setParseBigDecimal(true);
    format.setDecimalFormatSymbols(symbols);
    return format;
}