通过Spring实现servlet的复用

来源:互联网 发布:北京市空气质量数据 编辑:程序博客网 时间:2024/06/05 20:11

通过Spring实现servlet的复用

Auth-date: [add by Easzz 2017-06-15]

为什么需要servlet的复用

  1. 因为懒,如果不复用,那需要写很多个servlet(当然如果是用springmvc等框架就不需要了),同时web.xml里面也需要加配置,会有些麻烦。
  2. 减少项目代码量,体现java的面向对象设计思想,提高生产效率,增强可维护性。

复用的思路

  1. java的复用是通过继承来实现的,而继承很大一部分是为实现多态来准备的。通过多态,我们可以很好的实现类的复用,而不需要写很多重复性的代码,让程序更加的健壮。
  2. 前台向后台提交或者请求数据,会根据功能来请求,例如构造这样的请求
    /ListServlet?type=getCusUser&className=userService
    用于查询特定的用户,listServet是查询的通用servlet,type用于指定某个具体的查询方法,className为想要调用的service层

项目的结构

其中basic为一些通用类,biz中为业务包,这里是通过功能来分类的,比如商品和用户两个功能。

项目详解

使用spring之后,对象都是交由spring来管理,我们首先需要从spring bean容器中获得所需要的类

通过listener获得spring的context,放入我们自己写的AppSpringContext中,方便后续的调用

/** * 用于存放spring context  */public class AppSpringContext {    private AppSpringContext() {    }    private ApplicationContext context;    private static AppSpringContext appSpringContext;    public static AppSpringContext getInstance() {        if (appSpringContext == null) {            appSpringContext = new AppSpringContext();        }        return appSpringContext;    }    public void setContext(ApplicationContext context) {        this.context = context;    }    public ApplicationContext getContext() {        return context;    }}/** * 初始化,用于将spring context 放入AppSpringContext中 */public class StartupListener extends ContextLoaderListener {    @Override    public void contextInitialized(ServletContextEvent event) {        super.contextInitialized(event);        ServletContext servletContext = event.getServletContext();        WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);        AppSpringContext instance = AppSpringContext.getInstance();        //设置context        instance.setContext(context);    }}

在web.xml中添加

<listener>        <listener-class>com.easzz.basic.listener.StartupListener</listener-class></listener>

我们需要一个通用的service接口,其他的业务service均实现此接口,用于实现多态,其中里面有各种操作的方法。

public interface UniversalService {    /**     * 保存对象到数据库     *     * @param o     */    void saveObject(Object o);    /**     * 保存json串     *     * @param json     */    void saveObject(String json);    /**     * 查询数据库     *     * @param type 方法类型,用于区分不同的功能     * @param para     * @return     */    List<?> getJsonList(String type, Map<String, String> para);}

写到这里,我们思考一个问题,若其他的业务方法均实现此接口,如果里面的方法非常多,而且有些方法不一定需要实现。所以我们还需要一个通用的实现类,其他业务service继承此实现类即可,只需要重写自己所需要的方法

public class UniversalServiceImpl implements  UniversalService {    @Override    public void saveObject(Object o) {    }    @Override    public void saveObject(String json) {    }    @Override    public List<?> getJsonList(String type, Map<String, String> para) {        return null;    }}

servlet需要一个通用的查询servlet 继承BasicServlet,里面有获取bean的方法。

public abstract class BasicServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        execute(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        execute(req, resp);    }    public abstract void execute(HttpServletRequest req, HttpServletResponse resp);    /**     * 获取spring中的bean     * @param className  bean名称     * @return     */    protected UniversalService getAppBean(String className) {        AppSpringContext instance = AppSpringContext.getInstance();        ApplicationContext context = instance.getContext();        return (UniversalService) context.getBean(className);    }}public class ListServlet extends BasicServlet {    @Override    public void execute(HttpServletRequest req, HttpServletResponse resp) {        String className = req.getParameter("className");        String type = req.getParameter("type");        //通过getAppBean获得具体的实现类        UniversalService appBean = getAppBean(className);        List<?> jsonList = appBean.getJsonList(type, null);        //转json传前台    }}

前台请求这样的地址,就会调用上面的listServlet 并调用特定的方法 实现业务逻辑

ListServlet?type=getCusUser&className=userService

public class UserServiceImpl extends UniversalServiceImpl {    @Override    public void saveObject(String json) {        //super.saveObject(json);        System.out.println("user saveObject");    }    @Override    public List<?> getJsonList(String type, Map<String, String> para) {        if ("getCusUser".equals(type)) {            System.out.println("get custom user...");        }        return super.getJsonList(type, para);    }}

会进入里面重写的方法。

查询商品的地址

ListServlet?type=getItem&className=itemService

public class ItemServiceImpl extends UniversalServiceImpl {    @Override    public void saveObject(String json) {        //super.saveObject(json);        System.out.println("item saveObject");    }    @Override    public List<?> getJsonList(String type, Map<String, String> para) {        if ("getItem".equals(type)) {            System.out.println("get all items...");        }        return null;    }}

以上就是serlvet复用的基本思路

原创粉丝点击