设为首页收藏本站

IT技术擎 - 最棒的IT web技术交流社区

 找回密码
 注册为IT技术擎人

QQ登录

只需一步,快速开始

搜索
热搜: php h5 jquery
查看: 13|回复: 0

[其他] BaseServlet,让一个servlet处理多个请求

[复制链接]

5869

主题

5869

帖子

1万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
17963
发表于 2018-1-13 08:10:09 | 显示全部楼层 |阅读模式

BaseServlet
  第一次学习servlet的时候是跟着传智播客免费的教学视频,其中崔希凡讲的是我学过自认讲的最好的一位,BaseServlet也是跟着他写过一次,当时很多东西不能理解,后来慢慢发现其中的内层深意,本工具类在崔老师的基础之上增加了文件下载功能,如果能很好掌握,非常有利对struts2的掌握!1. 我们希望在一个Servlet中可以有多个请求处理方法!2. 客户端发出请求时,必须给出一个参数,来说明要调用哪一个方法3. 客户端必须传递名为method的参数
http://localhost:8080/test/UserServlet?method=login、http://localhost:8080/test/UserServlet?method=regist等等
原理  BaseServlet中调用request.getParameter("method")来确定你需要调用的方法,因为每次请求都是执行service方法,所以通过反射来执行
BaseServlet
  1. packagehui.zhang.servlet;
  2. importhui.zhang.down.DownUtils;
  3. importjava.io.File;
  4. importjava.io.FileInputStream;
  5. importjava.io.IOException;
  6. importjava.lang.reflect.Method;
  7. importjava.util.List;
  8. importjavax.servlet.ServletException;
  9. importjavax.servlet.ServletOutputStream;
  10. importjavax.servlet.http.HttpServlet;
  11. importjavax.servlet.http.HttpServletRequest;
  12. importjavax.servlet.http.HttpServletResponse;
  13. importorg.apache.commons.fileupload.FileItem;
  14. importorg.apache.commons.fileupload.disk.DiskFileItemFactory;
  15. importorg.apache.commons.fileupload.servlet.ServletFileUpload;
  16. importorg.apache.commons.io.IOUtils;
  17. /** * BaseServlet * 我们希望在一个Servlet中处理多个请求 * 创建Servlet时继承本类而不是继承HttpServlet,重写service方法 * 客户端在发起请求时需要传递method参数来判断调用哪个方法 * eg:http://localhost:8080/test/UserServlet?method=login * 返回值"f:/xxx"为转发、"r:/xxx"为重定向、"d:/xxx"为下载 * 重定向可以重定向到其他项目中,写法:"r:/192.168.11.24:8080/example/index.jsp" * 下载可以下载服务器中目录下的文件 "d:/WEB-INF/a.jpg" * 也可以下载磁盘绝对路径下的文件 "d:/G:/a.jpg" * @authorhui.zhang * */@SuppressWarnings("serial")
  18. publicclassBaseServlet extendsHttpServlet { @Override publicvoidservice(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8");//处理响应编码 //获取传递的method参数 String methodName = request.getParameter("method");if(methodName == null||methodName.trim().isEmpty()) {thrownewRuntimeException("没有传递method参数,不能确定要调用的方法!"); }//得到当前类的class对象 Class c =getClass(); Method method = null;try{ method =c.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); }catch(Exception e) {thrownewRuntimeException("要调用的方法:"+methodName+"(HttpServletRequest,HttpServletResponse),不存在!",e); }//调用method表示的方法 try{ String result = (String)method.invoke(this, request,response);/* * 获取请求处理方法执行后返回的字符串,它表示转发或重定向的路径 * 如果返回为null或者"",什么也不做 * 判断返回值中是否存在冒号,如果没有默认转发,因为转发的情况较多 * 如果有冒号,分割,得到前缀f表示forward,前缀r表示redirect * 后缀为要转发或重定向的路径 */ if(result == null||result.trim().isEmpty()) {return; }if(result.contains(":")) { //"f:/index.jsp" intindex = result.indexOf(":"); String s = result.substring(0, index); //f String path = result.substring(index+1); //"/index.jsp" if(s.equalsIgnoreCase("r")) {//"/192.168.11.24:8080/example/index.jsp" if(path.contains(":")) { //有:说明有端口号是其他项目的路径 if(path.contains("http")) {//"/http://192.168.11.24:8080/example/index.jsp" response.sendRedirect(path.substring(1)); }else{ response.sendRedirect("http://"+path.substring(1)); } }else{ response.sendRedirect(request.getContextPath()+path); } }elseif(s.equalsIgnoreCase("f")) { request.getRequestDispatcher(path).forward(request, response); }elseif(s.equalsIgnoreCase("d")) { //表示下载 /** * 两个头一个流 * 1. Content-Type * 2. Content-Disposition * 3. 流:下载文件的数据 */
  19. // path = "/WEB-INF/mp3/自娱自乐.mp3";
  20. // path = "/G://a.jpg"; intindexOf = path.lastIndexOf("/"); String name = path.substring(indexOf); ///自娱自乐.mp3 //如果包含:,说明是绝对路径 String filename = null;if(path.contains(":")) { filename = path.substring(1); }else{ //说明是服务器端文件,需要获得绝对路径 //获得文件的绝对路径 filename = this.getServletContext().getRealPath(path); }//去掉文件名前的/ name = name.substring(1); //自娱自乐.mp3 //通过DownUtils工具类处理不同浏览器下载时中文名乱码问题 String framename =DownUtils.filenameEncoding(name, request);//头1:获得要下载的文件MIME类型 String contentType = this.getServletContext().getMimeType(filename);//头2:ContentDisposition String contentDisposition = "attachment;filename="+framename; FileInputStream input = newFileInputStream(filename); response.setHeader("Content-Type", contentType); response.setHeader("Content-Disposition",contentDisposition); ServletOutputStream output =response.getOutputStream(); IOUtils.copy(input, output); input.close(); output.close(); }else{thrownewRuntimeException("操作:"+s+"目前还不支持!"); } }else{ //默认转发 request.getRequestDispatcher(result).forward(request, response); } }catch(Exception e) {thrownewRuntimeException("调用的方法:"+methodName+"(HttpServletRequest,HttpServletResponse),内部抛出异常!", e); } }
  21. }
复制代码

DownUtils
  1. /** * 文件下载时处理浏览器不同编码的中文乱码 * @authorhui.zhang * @date 2017-10-12 下午6:04:06 */
  2. publicclassDownUtils {publicstaticString filenameEncoding(String filename, HttpServletRequest request) throwsIOException{//获取浏览器头信息 String agent = request.getHeader("User-Agent");if(agent.contains("Firefox")){ BASE64Encoder base64Encoder = newBASE64Encoder(); filename = "=?utf-8?B?"+base64Encoder.encode(filename.getBytes("utf-8"))+"?="; }elseif(agent.contains("MSIE")){ filename = URLEncoder.encode(filename,"utf-8"); }else{ filename = URLEncoder.encode(filename,"utf-8"); }returnfilename; }
  3. }
复制代码
  代码中注释还算清楚,下载文件的功能是新加上的,测试还挺正常,如果使用出现问题欢迎提出!因为getParameter()在上传文件中失效,所以没写在Base中,后续也会传上来共同交流,感谢观看!
该用户未在地球留下任何的痕迹

本版积分规则

QQ|小黑屋|帮助|IT技术擎 ( 沪ICP备15054863号  

GMT+8, 2018-1-21 07:03

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表