赋料扬雄敌,诗看子建亲。这篇文章主要讲述Servlet开发 | 利用 Filter + 反射 处理 URL, 精简 servlet-mapping相关的知识,希望能为你提供帮助。
1.提要在原生 Servlet
开发中,如果采用一个 url 对应一个 servlet-mapping,那么web.xml将会十分冗长难以维护。其实,我们其实可以通过 Filter + 反射
来
使
一个 servlet
处理
多个 url ,并且根据不同url调用到 servlet
中的不同方法 (类似SpringMVC)
【Servlet开发 | 利用 Filter + 反射 处理 URL, 精简 servlet-mapping】根据下面的代码实现之后,可以实现
用户访问 /test的时候,就会自动调用 FrontServlet
下面
的 test()
方法,并且根据
该
方法的返回值
来
返回 jsp
文件
或者是 跳转,用户访问 /test2
的时候,就会调用 test2()
方法,以此类推。
本文是
小小商城-Servlet版的
细节详解系列 之一,项目 github:https://github.com/xenv/S-mall-servlet/
本文代码大部分在 github 中
可以找到
2.具体实现完整的实现代码见:https://github.com/xenv/S-mall-servlet/blob/master/src/filter/BackServletFilter.java
1. 创建 Filter
文件,implements Filter ,override
doFilter
方法
2.
在doFilter
方法中获取 uri
//获取根容器目录 String contextPath = request.getServletContext().getContextPath(); //获取完整 uri String uri= request.getRequestURI(); //除根 uri 根目录 uri = StringUtils.remove(uri,contextPath);
3. 根据不同的 uri ,获取到对应的 函数 名,插入到request中,比如,我们简单在这里直接把根目录下的 uri 直接 转成 函数 名
if(!(uri.contains(".") || (uri.lastIndexOf(‘/‘)> 0))){ // 根目录 不含.的 uri String method = uri.substring(1); request.setAttribute("method",method); String servletPath = "front.servlet"; request.getRequestDispatcher(servletPath).forward(request,response); ... } //其他请求放行 filterChain.doFilter(request,response);
4. 根据不同的uri,调用 Servlet,比如,我们简单在这里直接 调用 一个固定的 servlet
String servletPath = "front.servlet";
request.getRequestDispatcher(servletPath).forward(request,response);
5. 在Servlet中,重写service方法,我们读取 刚刚传进来的 method ,反射调用相关方法,并把 request 和 responce 传进去
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws xception { String method = (String)req.getAttribute("method"); //利用反射把url中的方法文本转化为方法进行调用 req.setCharacterEncoding("utf-8"); Method m = this.getClass().getMethod(method,HttpServletRequest.class,HttpServletResponse.class); String redirect = m.invoke(this,req,resp).toString(); if(redirect.startsWith("@")){ resp.sendRedirect(redirect.substring(1)); }else if(redirect.startsWith("%")) resp.getWriter().print(redirect.substring(1)); else req.getRequestDispatcher(redirect).forward(req, resp); }
在这里,我们的method会返回一个String,如果这个String是 @ 开头,那么是跳转,相当于 Springmvc 的 (redirect:) ,如果是 %开头,则是返回纯文本,其他开头则 调用那个 JSP (相当于 Springmvc 的视图定位)
对于非法访问的情况,可能会出错,我们必须要进行错误处理,这里只是简单一个简单演示
6.在具体method中,我们需要接受 request 和 responce,返回String,例如
public String delete(HttpServletRequest request , HttpServletResponse response){ int id = Integer.parseInt(request.getParameter("id")); service.delete(id); return "@/admin/category_list"; }
7.在web.xml配置 filter 和 servlet
< filter> < filter-name> BackServletFilter< /filter-name> < filter-class> filter.BackServletFilter< /filter-class> < /filter> < filter-mapping> < filter-name> BackServletFilter< /filter-name> < url-pattern> /*< /url-pattern> < /filter-mapping> < servlet> < servlet-name> FrontServlet< /servlet-name> < servlet-class> servlet.FrontServlet< /servlet-class> < /servlet> < servlet-mapping> < servlet-name> FrontServlet< /servlet-name> < url-pattern> /front.servlet< /url-pattern> < /servlet-mapping>
这样,用户访问 /test的时候,就会自动调用 Frontservlet 下面 的 test() 方法,并且根据 该 方法的返回值 来 返回 jsp 文件 或者是 跳转
3.重新理顺一次用户访问 url ,先到 Filter ,filter 根据 url ,获取相应的 method 和 servlet ,然后 filter 把控制权交给 servlet, serlvet再根据 method 调用 具体的方法,返回要加载 jsp 文件 或者 跳转,这样我们就实现了和 SpringMVC 大致一样的效果。
推荐阅读
- 勇闯天塔 (TOTEM) 游戏下载 | 手机游戏免费下载 | 安卓版免费下载 | Android版本免费下载 - 解谜游戏 闯关游戏 冒险游戏
- Hybrid APP架构设计思路
- Eclipse+ADT+Android SDK 搭建安卓开发环境(转)
- App 区别
- Android 音视频深入 十七 FFmpeg 获取RTMP流保存为flv (附源码下载)
- Appium Desired Capabilities信息配置
- NetApp7mode环境下配置VSCAN
- MATLAB高斯和高斯-乔丹消除
- Win10 Windows无法访问局域网共享电脑的处理办法