一.功能
封装多个请求,在一个Servelt中处理。原型 = 返回值类型 + 方法名称 + 参数列表
二.实现
2.1 基类重写HttpServelt,通过反射调用实现子类的方法,根据request.getParameter(“method”)获取子类的方法名,统一处理请求。
public class BaseServlet extends HttpServlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if(request.getMethod().equalsIgnoreCase("get")) {
if(!(request instanceof GetRequest)) {
request = new GetRequest(request);//处理get请求编码
}
} else {
request.setCharacterEncoding("utf-8");//处理post请求编码
}
response.setContentType("text/html;charset=UTF-8");//处理响应编码
/**
* 1. 获取method参数,它是用户想调用的方法 2. 把方法名称变成Method类的实例对象 3. 通过invoke()来调用这个方法
*/
String methodName = request.getParameter("method");
Method method = null;
/**
* 2. 通过方法名称获取Method对象
*/
try {
method = this.getClass().getMethod(methodName,
HttpServletRequest.class, HttpServletResponse.class);
} catch (Exception e) {
throw new RuntimeException("您要调用的方法:" + methodName + "它不存在!", e);
}
/**
* 3. 通过method对象来调用它
*/
try {
String result = (String)method.invoke(this, request, response);
if(result != null && !result.trim().isEmpty()) {//如果请求处理方法返回不为空
int index = result.indexOf(":");//获取第一个冒号的位置
if(index == -1) {//如果没有冒号,使用转发
request.getRequestDispatcher(result).forward(request, response);
} else {//如果存在冒号
String start = result.substring(0, index);//分割出前缀
String path = result.substring(index + 1);//分割出路径
if(start.equals("f")) {//前缀为f表示转发
request.getRequestDispatcher(path).forward(request, response);
} else if(start.equals("r")) {//前缀为r表示重定向
response.sendRedirect(request.getContextPath() + path);
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
2.2 对get请求进行编码处理
/**
* 对GET请求参数加以处理!
* @author qdmmy6
*
*/
public class GetRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
public GetRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
// 获取参数
String value = request.getParameter(name);
if(value == null) return null;//如果为null,直接返回null
try {
// 对参数进行编码处理后返回
return new String(value.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override
public Map getParameterMap() {
Map<String,String[]> map = request.getParameterMap();
if(map == null) return map;
// 遍历map,对每个值进行编码处理
for(String key : map.keySet()) {
String[] values = map.get(key);
for(int i = 0; i < values.length; i++) {
try {
values[i] = new String(values[i].getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
// 处理后返回
return map;
}
}
2.3 实现BaseServlet
public class CustomerServlet extends BaseServlet {
private CustomerService customerService = new CustomerService();
public String add(HttpServletRequest request, HttpServletResponse response) {
//...
return "/msg.jsp";//定义表单提交返回的页面
}
public String findAll(HttpServletRequest request, HttpServletResponse response) {
//...
return "f:/list.jsp";
}
}
public String preEdit(HttpServletRequest request, HttpServletResponse response) {
//...
return "/edit.jsp";
}
}
三.总结
将同一功能的多个请求封装在一个Servelt里统一处理,既减少了书写多个Servelt,又方便管理。