BaseServlet的编写

在BaseServlet之前,需要提及工厂factory去管理dao以及service,以及页面转发或重定向的管理

1.创建一个工厂类,以及一个资源文件,资源文件中以键值对的形式去存储key,以及对应的类的路径。工厂类中通过key拿到类的路径,通过这个路径反射的到对象。

public class BeanFactory {
    
    //加载配置文件
    private static ResourceBundle bundle;
    static{
        bundle = ResourceBundle.getBundle("instance");
    }
    
    /**
     * 根据指定的key,读取配置文件获取类的全路径,创建对象
     */
    
    public static <T> T getInstance(String key,Class<T> clazz){
        String className = bundle.getString(key);
        
        try {
            return (T) Class.forName(className).newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        
    }
}

2.将重定向以及转发的操作提取出来,放到WebUtil类中,作为一个静态方法。静态方法中有一个uri参数,根据它类型的不同去考虑是转发还是重定向。

public class WebUtil {

    /**
     * 页面跳转通用方法
     */
    public static void goTo(HttpServletRequest req,HttpServletResponse resp, Object uri) throws ServletException, IOException{
        if (uri instanceof RequestDispatcher) {
            ((RequestDispatcher) uri).forward(req, resp);
        } else if (uri instanceof String){
            resp.sendRedirect(req.getContextPath() + uri);
        }
    }
}

每个Servlet在启动之后都会去自动调用service方法,而service方法会去调用doGet()或者doPost(),同时在servlet中都需要去实例化service实例对象,所以可以把实例化service对象的操作以及,doGet()和doPost()编写在BaseServlet中,让其他的servlet去继承BaseServlet,当然BaseServlet类肯定是要继承HttpServlet类的

public abstract class BaseServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;
    
    //注意要用protected
    protected ServiceA serviceA = BeanFactory.getInstance("serviceA", ServiceA.class);
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object returnValue = null;
        //获取操作类型;
        String methodName = req.getParameter("method");
        try {
            //1.获取当前运行类的字节码
            Class clazz = this.getClass();
            //2.获取当前执行的方法的Method类型
            Method method = clazz.getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
            //3.执行方法
            returnValue = method.invoke(this, req,resp);
        } catch (Exception e) {
            e.printStackTrace();
            returnValue = "/error/error.jsp";
        }
        WebUtil.goTo(req, resp, returnValue);
        
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

在请求转发的时候,url中会有路径加servlet以及方法名(method的值需要与servlet中编写的方法的名称相同),通过获取method中的值,拿到方法名,然后让当前运行类去调用该方法。

这样的话,其他的servlet只需要去编写方法就好了,不需要写doGet()以及doPost(),因为,在某一个servlet启动的时候,自动调用找不到doGet或者doPost方法就会去父类去找,这样就会调用父类中的上述代码,然后调用相应的方法。

posted @ 2019-01-27 23:39  程序员deepz  阅读(503)  评论(0编辑  收藏  举报