在之前学的web项目流程里面,一次跳转基本就得对应一个相应的Servlet给它使用。但是在商城项目里面的跳转会特别多,每个页面的增删改查都得需要对应的Servlet,项目就会特别的臃肿。
然后站长就教了个方法,用Filter和Servlet配合,利用java里面的反射机制,减少Servlet类的数量。
流程是这样的!
比如要访问的页面是 http://127.0.0.1:8080/tmall/admin_category_list,
1、设置filter : BackServletFilter把这个页面拦截下来,并用字符串工具类把admin_category_list取出来。
2、然后把里面的category,list分别用字符串工具拿出来,组成uri:categoryServlet,方法:list
3、根据组成的categoryServlet,利用服务器跳转跳转到对应名称的Servlet。并用request.attribute把方法list传过去。
4、由于categoryServlet继承了BaseBackServlet,就会自动调用父类的service方法,在service方法中。利用反射技术,根据传过来的方法list,调用categoryServlet中对应的方法。
换句话说:
如果访问的路径是admin_category_add,就会调用categoryServlet.add()方法
如果访问的路径是admin_category_delete,就会调用categoryServlet.delete()方法
如果访问的路径是admin_category_edit,就会调用categoryServlet.edit()方法
如果访问的路径是admin_category_update,就会调用categoryServlet.update()方法
如此这般,一个categoryServlet类,就完成了本来需要5个Servlet类才能完成的功能。
代码:
package tmall.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
public class BackServletFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse) res;
String contextPath = request.getServletContext().getContextPath(); //拿到/tmall/admin_xxx_xx地址
String uri=request.getRequestURI();//拿到/tmall
uri=StringUtils.remove(uri,contextPath);//把contextPath中的/tamll去掉,得到单纯的admin_xxx_xx地址
if(uri.startsWith("/admin_")){
String servletPath = StringUtils.substringBetween(uri, "_","_")+"Servlet";//拿到servlet名字
String method = StringUtils.substringAfterLast(uri, "_");//拿到方法名
request.setAttribute("method",method);
request.getRequestDispatcher("/"+servletPath);//跳转到对应的servlet
return;
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
categoryServlet里面反射机制的代码:
String method = (String) request.getAttribute("method");
Method m = this.getClass().getMethod(method, javax.servlet.http.HttpServletRequest.class,
javax.servlet.http.HttpServletResponse.class,Page.class);
String redirect = m.invoke(this,request, response,page).toString();