package com.test.servlet;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
@SuppressWarnings("serial")
public class CommonServlet extends HttpServlet {
protected HttpServletRequest request;
protected HttpServletResponse resposne;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
process(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
process(req, resp);
}
protected void process(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
request = req;
resposne = resp;
try {
initEntity();
} catch (Exception e){e.printStackTrace();}
try {
String method = (String)req.getAttribute("method");
if(method == null) throw new Exception("Could not find any method to invoke!");
this.getClass().getMethod(method).invoke(this);
} catch (Exception e){e.printStackTrace();}
}
/**
* 从request中获取参数来初始化servlet中定义的实体,servlet定义的实体必须提供标准的getter和setter
* servlet里的对象实体应该先初始化,实体中的自定义实体也应该先初始化,例如:
* Employee中有Date这个属性和Address这个自定义属性,那么再Employee初始化时,必须得初始化好Address,
* Date可以不用初始化,因为他是Java里定义的。
* public class Employee {
* private Date birthday;
* private Address address;
* public Employee() {
* address = new Address();
* }
* }
*
* 前台中的参数name定义应遵循以下规则:
* example,假设MyServlet的属性都提供了getter和setter
* public class MyServlet {
* private int id;
* private String name;
* private Employee employee;//假设employee中有name属性
* }
* 1.servlet里的基本类型可直接使用属性名作为参数名 <input type='text' name='id'>
* 2.servlet里的对象实体的属性用 实体.属性 定义,如<input type='text' name='employee.name'>
* 假如employee中还有另一个对象作为属性,可再用.来进入下层,如 employee.address.city
* @throws Exception
*/
@SuppressWarnings("unchecked")
protected void initEntity() throws Exception {
Map<String, Object> entities = new HashMap<String, Object>();//实体
//各个实体所对应的键/值,实体作为键,属性/值的map作为值
Map<Object, Map<String, String>> propertiesOfEntity = new HashMap<Object, Map<String, String>>();
Enumeration<String> names = request.getParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
String value = request.getParameter(name);
/*
* 如果参数名中没有带有"."的话,表示该参数名是servlet中定义的一个基础类型,
* 则后面会将entity设置为servlet本身
*/
boolean self = name.indexOf(".") == -1;
Object entity = saveEntity(entities, name, self);
//如果实体为servlet本身,则直接取name作为属性名,否则将第一个"."的右边作为属性名
//如employee.department.name,则取department.name作为属性名
String property = self ? name : name.substring(name.indexOf(".") + 1, name.length());
saveProperty(propertiesOfEntity, entity, property, value);
}
//将属性值注入到servlet里定义的各个实体中
for(String entityKey : entities.keySet()) {
Object entity = entities.get(entityKey);
Map<String, String> m = propertiesOfEntity.get(entity);
BeanUtils.populate(entity, m);
}
}
/**
* 将实体保存到一个map中,首先会从entities中以name获取该实体,如果为空,则实例一个保存到entities中,
* 如果self为true,表示该实体应该是servlet本身,否则从servlet中获取该实体
* @param entities 实体map
* @param name 作为实体的键
* @param self 实体是否是servlet本身,如果为true表示是实体是servlet本身
* @return
* @throws Exception
*/
private Object saveEntity(Map<String, Object> entities, String name, boolean self) throws Exception {
if(!self) name = name.substring(0, name.indexOf("."));
Object entity = entities.get(name);
if(entity == null) {
entity = self ? this : PropertyUtils.getProperty(this, name);
entities.put(name, entity);
}
return entity;
}
/**
* 保存实体的属性值
* @param propertiesOfEntity 某个实体的属性值map
* @param entity 作为属性值map的键,以实体作为键
* @param property 属性名
* @param value 属性值
*/
private void saveProperty(Map<Object, Map<String, String>> propertiesOfEntity,
Object entity, String property, String value) {
Map<String, String> properties = propertiesOfEntity.get(entity);
if(properties == null) {
properties = new HashMap<String, String>();
}
properties.put(property, value);
propertiesOfEntity.put(entity, properties);
}
}