通过Spring实现servlet的复用

通过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复用的基本思路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值