通过Spring实现servlet的复用
Auth-date: [add by Easzz 2017-06-15]
为什么需要servlet的复用
- 因为懒,如果不复用,那需要写很多个servlet(当然如果是用springmvc等框架就不需要了),同时web.xml里面也需要加配置,会有些麻烦。
- 减少项目代码量,体现java的面向对象设计思想,提高生产效率,增强可维护性。
复用的思路
- java的复用是通过继承来实现的,而继承很大一部分是为实现多态来准备的。通过多态,我们可以很好的实现类的复用,而不需要写很多重复性的代码,让程序更加的健壮。
- 前台向后台提交或者请求数据,会根据功能来请求,例如构造这样的请求
/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复用的基本思路