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. package hui.zhang.servlet;
  2.  
  3. import hui.zhang.down.DownUtils;
  4.  
  5. import java.io.File;
  6. import java.io.FileInputStream;
  7. import java.io.IOException;
  8. import java.lang.reflect.Method;
  9. import java.util.List;
  10.  
  11. import javax.servlet.ServletException;
  12. import javax.servlet.ServletOutputStream;
  13. import javax.servlet.http.HttpServlet;
  14. import javax.servlet.http.HttpServletRequest;
  15. import javax.servlet.http.HttpServletResponse;
  16.  
  17. import org.apache.commons.fileupload.FileItem;
  18. import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  19. import org.apache.commons.fileupload.servlet.ServletFileUpload;
  20. import org.apache.commons.io.IOUtils;
  21.  
  22. /**
  23. * BaseServlet
  24. * 我们希望在一个Servlet中处理多个请求
  25. * 创建Servlet时继承本类而不是继承HttpServlet,重写service方法
  26. * 客户端在发起请求时需要传递method参数来判断调用哪个方法
  27. * eg:http://localhost:8080/test/UserServlet?method=login
  28. * 返回值"f:/xxx"为转发、"r:/xxx"为重定向、"d:/xxx"为下载
  29. * 重定向可以重定向到其他项目中,写法:"r:/192.168.11.24:8080/example/index.jsp"
  30. * 下载可以下载服务器中目录下的文件 "d:/WEB-INF/a.jpg"
  31. * 也可以下载磁盘绝对路径下的文件 "d:/G:/a.jpg"
  32. * @author hui.zhang
  33. *
  34. */
  35. @SuppressWarnings("serial")
  36. public class BaseServlet extends HttpServlet {
  37. @Override
  38. public void service(HttpServletRequest request, HttpServletResponse response)
  39. throws ServletException, IOException {
  40. request.setCharacterEncoding("UTF-8");
  41. response.setContentType("text/html;charset=UTF-8");//处理响应编码
  42.  
  43. //获取传递的method参数
  44. String methodName = request.getParameter("method");
  45. if (methodName == null || methodName.trim().isEmpty()) {
  46. throw new RuntimeException("没有传递method参数,不能确定要调用的方法!");
  47. }
  48. //得到当前类的class对象
  49. Class c = getClass();
  50. Method method = null;
  51. try {
  52. method = c.getMethod(methodName,
  53. HttpServletRequest.class,HttpServletResponse.class);
  54. } catch (Exception e) {
  55. throw new RuntimeException("要调用的方法:"+methodName+"(HttpServletRequest,HttpServletResponse),不存在!",e);
  56. }
  57. //调用method表示的方法
  58. try {
  59. String result = (String)method.invoke(this, request,response);
  60. /*
  61. * 获取请求处理方法执行后返回的字符串,它表示转发或重定向的路径
  62. * 如果返回为null或者"",什么也不做
  63. * 判断返回值中是否存在冒号,如果没有默认转发,因为转发的情况较多
  64. * 如果有冒号,分割,得到前缀f表示forward,前缀r表示redirect
  65. * 后缀为要转发或重定向的路径
  66. */
  67. if (result == null || result.trim().isEmpty()) {
  68. return;
  69. }
  70. if (result.contains(":")) { //"f:/index.jsp"
  71. int index = result.indexOf(":");
  72. String s = result.substring(0, index); //f
  73. String path = result.substring(index+1); // "/index.jsp"
  74. if (s.equalsIgnoreCase("r")) {
  75. // "/192.168.11.24:8080/example/index.jsp"
  76. if (path.contains(":")) { //有:说明有端口号是其他项目的路径
  77. if (path.contains("http")) {
  78. // "/http://192.168.11.24:8080/example/index.jsp"
  79. response.sendRedirect(path.substring(1));
  80. } else {
  81. response.sendRedirect("http://"+path.substring(1));
  82. }
  83. } else {
  84. response.sendRedirect(request.getContextPath()+path);
  85. }
  86. } else if (s.equalsIgnoreCase("f")) {
  87. request.getRequestDispatcher(path).forward(request, response);
  88. } else if (s.equalsIgnoreCase("d")) { //表示下载
  89. /**
  90. * 两个头一个流
  91. * 1. Content-Type
  92. * 2. Content-Disposition
  93. * 3. 流:下载文件的数据
  94. */
  95. // path = "/WEB-INF/mp3/自娱自乐.mp3";
  96. // path = "/G://a.jpg";
  97. int indexOf = path.lastIndexOf("/");
  98. String name = path.substring(indexOf); // /自娱自乐.mp3
  99. //如果包含:,说明是绝对路径
  100. String filename = null;
  101. if (path.contains(":")) {
  102. filename = path.substring(1);
  103. } else { //说明是服务器端文件,需要获得绝对路径
  104. //获得文件的绝对路径
  105. filename = this.getServletContext().getRealPath(path);
  106. }
  107. //去掉文件名前的/
  108. name = name.substring(1); // 自娱自乐.mp3
  109. //通过DownUtils工具类处理不同浏览器下载时中文名乱码问题
  110. String framename = DownUtils.filenameEncoding(name, request);
  111. //头1:获得要下载的文件MIME类型
  112. String contentType = this.getServletContext().getMimeType(filename);
  113. //头2:ContentDisposition
  114. String contentDisposition = "attachment;filename="+framename;
  115. FileInputStream input = new FileInputStream(filename);
  116. response.setHeader("Content-Type", contentType);
  117. response.setHeader("Content-Disposition",contentDisposition);
  118. ServletOutputStream output = response.getOutputStream();
  119. IOUtils.copy(input, output);
  120. input.close();
  121. output.close();
  122. } else {
  123. throw new RuntimeException("操作:"+s+"目前还不支持!");
  124. }
  125.  
  126. } else { //默认转发
  127. request.getRequestDispatcher(result).forward(request, response);
  128. }
  129. } catch (Exception e) {
  130. throw new RuntimeException("调用的方法:"+methodName+"(HttpServletRequest,HttpServletResponse),内部抛出异常!", e);
  131. }
  132.  
  133. }
  134.  
  135. }

DownUtils

  1. /**
  2. * 文件下载时处理浏览器不同编码的中文乱码
  3. * @author hui.zhang
  4. * @date 2017-10-12 下午6:04:06
  5. */
  6. public class DownUtils {
  7. public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException{
  8. //获取浏览器头信息
  9. String agent = request.getHeader("User-Agent");
  10. if(agent.contains("Firefox")){
  11. BASE64Encoder base64Encoder = new BASE64Encoder();
  12. filename = "=?utf-8?B?"+base64Encoder.encode(filename.getBytes("utf-8"))+"?=";
  13. } else if(agent.contains("MSIE")){
  14. filename = URLEncoder.encode(filename,"utf-8");
  15. } else {
  16. filename = URLEncoder.encode(filename,"utf-8");
  17. }
  18. return filename;
  19. }
  20.  
  21. }

  代码中注释还算清楚,下载文件的功能是新加上的,测试还挺正常,如果使用出现问题欢迎提出!因为getParameter()在上传文件中失效,所以没写在Base中,后续也会传上来共同交流,感谢观看!

BaseServlet,让一个servlet处理多个请求的更多相关文章

  1. Servlet(五):一个Servlet处理多个请求

    一.为什么要使用一个Servlet来处理多个请求? 当浏览器发送了一次请求到服务器时,servlet容器会根据请求的url-pattern找到对应的Servlet类,执行对应的doPost或doGet ...

  2. 一个servlet处理多个请求(使用Method的反射机制)

    方法一 可以通过在请求的时候加上参数,然后在servlet中获取请求的参数,再去调用对应的方法.达到一个servlet处理多个请求的目的 test.jsp: <%@ page language= ...

  3. 如何用一个servlet处理多个请求

    一个servlet处理多个请求,原理:利用反射机制获取在selvlet类中的其他方法1.前端页面<%@ page language="java" contentType=&q ...

  4. 【WEB小工具】BaseServlet—一个Servlet处理多个请求

    package cn.itcast.test.web.servlet; import java.io.IOException; import java.io.PrintWriter; import j ...

  5. 怎么在一个servlet中实现多个功能 ?如何使一个Servlet处理多个请求?

    自学javaweb一直不知道一个servelt可以有多个功能!看了别人代码才知道这个可以有! 平时你建立servelt时候你会吧doget和dopost这两个勾上,要想实现多个功能,你不必要勾选dog ...

  6. 一个servlet处理多个请求或者叫方法

    http://blog.csdn.net/qq_25201665/article/details/52037607

  7. 一个servlet如何处理多个请求

    页面1:表单的action=login?method=login 页面2:表单的action=login?method=insert ..... 然后通过method的值采用不同方法进行处理. 如下 ...

  8. Tomcat是一个Servlet容器?

    "Tomcat是一个Servlet容器",这句话对于2019年的程序员应该是耳熟能详的. 单纯的思考一下这句话,我们可以抽象出来这么一段代码: class Tomcat { Lis ...

  9. (二)第一个Servlet

    一.预备知识 一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个 ...

随机推荐

  1. xml字符串转对象xml文件转对象

    判断是否是ie浏览器和非ie浏览器的方法有多种,在此只介绍用例中的方法: 1.解析xml字符串,得到xml对象的方式: function createXml(str){ if(document.all ...

  2. [我所理解的REST] 3.基于网络应用的架构

    上篇中解释到什么是架构风格和应该以怎样的视角来理解REST(Web的架构风格).本篇来介绍一组自洽的术语,用它来描述和解释软件架构:以及列举下对于基于网络的应用来说,哪些点是需要我们重点关注的. 1 ...

  3. 联想G50-70安装SSD及WIN10教程

    借着双11的东风,果断入手SSD120G和4G内存条1枚.经过近一周的安装与试运行,笔者实现了SSD+HDD双硬盘+WIN10系统.目前运行体验非常好,开机时间9秒,软件运行也非常流畅.在折腾的过程中 ...

  4. 201521123121 《JAVA程序设计》第7周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 参考资料: XMind 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList的contains源代码 ...

  5. 201521123006 《java程序设计》 第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...

  6. Java课程设计——计算器团队博客

    1.团队名称.团队成员介绍(需要有照片) 1.1团队名称 707 1.2团队成员介绍 谢元将:组长 罗登宇:组员 王华俊:组员 2. 项目git地址 谢元将 罗登宇 王华俊 3. 项目git提交记录截 ...

  7. DAU新解

    写在回归之时 --------------------------- 抱歉,已经超过三年没有回到这里了. 浮躁,虚荣,一颗心没有落到地上,也没有好好总结一下自己.怀念最开始那个时候的状态,安静的做点事 ...

  8. MySQL数据库引擎介绍、区别

    数据库引擎介绍 MySQL数据库引擎取决于MySQL在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另 ...

  9. informix服务端口和oralce服务端口

    查找informix的服务端口1>>more .profile 找到: INFORMIXDIR=/home/informix INFORMIXSERVER=aaaa2>>cd ...

  10. idea使用转载【别人的专栏】

    维C果糖