分頁及查詢引數傳遞問題分享

freebox發表於2008-06-28
一、問題:經常碰到查詢問題,查詢引數需要放在request中,並保證無論是第一次Post,還是以後分頁時的get,都能正確取到這些值。於是做了一個小工具,讓這種操作更方便,並可用於hql查詢(不用hql這功能也可,它還不完善)
二、需要支援:
1、JSON:http://www.json.org/,到這裡找forJava的,包名為org.json
2、JDK5
三、程式碼:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface QueryParam {}
/**
 * JSON 拆解、裝配工具
 */
public class JsonUtil {
	private static final Log LOG = LogFactory.getLog(JsonUtil.class);
	private static final DateFormat dateFormat = DateFormat
			.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);

	/**
	 * 將JSON字串裝配成物件
	 * 
	 * @param jsonString
	 *            JSON字串
	 * @param object
	 *            被裝配的目標物件
	 */
	public static void assemble(String jsonString, Object object) {
		try {
			JSONObject json = new JSONObject(jsonString);
			Field fields[] = object.getClass().getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				QueryParam param = field.getAnnotation(QueryParam.class);
				if (param == null) {
					continue;
				}
				if (JSONObject.NULL == json.get(field.getName())) {
					field.set(object, null);
					continue;
				}
				Type type = field.getType();
//雖然我知道可以用其它形式書寫下面這些,不過就這麼幾個,將就一下吧
				if (type == Integer.class) {
					field.set(object, json.getInt(field.getName()));
				} else if (type == Double.class) {
					field.set(object, json.getDouble(field.getName()));
				} else if (type == Long.class) {
					field.set(object, json.getLong(field.getName()));
				} else if (type == Boolean.class) {
					field.set(object, json.getBoolean(field.getName()));
				} else if (type == Date.class) {
					String dateString = json.getString(field.getName());
					field.set(object, dateFormat.parse(dateString));
				} else {
					field.set(object, json.getString(field.getName()));
				}
			}
		} catch (JSONException e) {
			LOG.debug(e);
		} catch (IllegalArgumentException e) {
			LOG.debug(e);
		} catch (IllegalAccessException e) {
			LOG.debug(e);
		} catch (ParseException e) {
			LOG.debug(e);
		}
	}

	/**
	 * 將物件拆解成JSON字串
	 * 
	 * @param object
	 *            被拆解的物件
	 * @return JSON字串
	 */
	public static String disassemble(Object object) {
		try {
			Field fields[] = object.getClass().getDeclaredFields();
			JSONStringer json = new JSONStringer();
			JSONWriter writer = json.object();
			for (Field field : fields) {
				field.setAccessible(true);
				QueryParam param = field.getAnnotation(QueryParam.class);
				if (param == null) {
					continue;
				}
				Type type = field.getType();
				if (type == Date.class) {
					Date date = (Date) field.get(object);
					writer.key(field.getName()).value(dateFormat.format(date));
				} else {
					writer.key(field.getName()).value(field.get(object));
				}
			}
			writer.endObject();
			return writer.toString();
		} catch (JSONException e) {
			LOG.debug(e);
		} catch (IllegalArgumentException e) {
			LOG.debug(e);
		} catch (IllegalAccessException e) {
			LOG.debug(e);
		}
		return null;
	}
}
<p class="indent">

web中的一小段程式碼:

//這些都需要您從request裡取得
//QueryComponent queryComponent
//String param
if (params != null) {
	// get提交
	JsonUtil.assemble(params, queryComponent);
	setQueryComponent(queryComponent);
} else {
	// post提交
	if (queryComponent != null) {
		params = JsonUtil.disassemble(queryComponent);
	}
}
request.setAttribute("params", params);
<p class="indent">

利用上面的工具,可以在連線中建立查詢字串,例如?index=1&param={"name":"Json"},點選連線,param後的JSON串會被組裝成查詢物件。
下面這些是給hql查詢用的。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Hql {
	/**
	 * hql查詢語句
	 */
	public abstract String hql();
}
<p class="indent">

//這個是在QueryComponent中欄位上設定的註釋,不加此註釋將不作為查詢用。並針對like查詢的%問題,left表示左側有%,no表示此欄位不使用like匹配

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface HqlParam {
	public enum like {
		left, right, all,no;
	}

	public abstract HqlParam.like like() default HqlParam.like.no;
}
<p class="indent">

相關文章