Servlet是什么
Servlet(Server + Applet),一个Servlet就是一个Java类,并提供 基于请求-响应模式 的Web服务。
要使用servlet需要添加javax.servlet-api
Jar包(时代变了)jakarta.servlet-api
。
Servlet的处理流程
接收客户端的HTTP请求路径及请求内容
根据web.xml(属于web应用程序的一部分,部署描述符),找到请求路径对应的Servlet
1 2 3 4 5 6 7 8 9
| ... <servlet> <servlet-name>servlet名称(最好与类名相同)</servlet-name> <servlet-class>类路径</servlet-calss> </servlet> <servlet-mapping> <servlet-name>与<servlet>元素中的该元素内容相同</servlet-name> <url-pattern>映射路径</url-pattern> </servlet-mapping>
|
将请求转发给Servlet对应的service方法(会传递HttpServletRequest对象和HttpServletResponse对象作为方法参数)
service方法根据请求是 get/post/… 转发给 doGet/doPost方法处理
通过HttpResponse对象,将响应返回给客户端
Servlet生命周期
init → service(doGet、doPost…) → destroy
管理Servlet的配置信息
通过ServletConfig
对象获取配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ... <servlet> <init-param> <param-name>参数名1</param-name> <param-value>参数值1</param-value> </init-param> ... <servlet-name>servlet名称(最好与类名相同)</servlet-name> <servlet-class>类名</servlet-calss> </servlet> <servlet-mapping> <servlet-name>与<servlet>元素中的该元素内容相同</servlet-name> <url-pattern>映射路径</url-pattern> </servlet-mapping>
|
每个Servlet支持设置多个<init-param>
,Servlet初始化过程中,<init-param>
参数将被封装到ServletConfig
对象中。在Servlet中,通过调用ServletConfig对象,就可以利用配置信息:
1 2
| ServletConfig config = this.getServletConfig(); String value1 = config.getParameter("参数名1");
|
通过ServletContext
共享Servlet的配置信息
Servlet容器在启动时,会为每个Web应用创建一个对应的ServletContext
对象,它代表当前的Web应用。在一个Servlet中保存的数据,可以在另一个Servlet中获取。
1 2 3 4 5
| <context-param> <param-name>参数名1</param-name> <param-value>参数值1</param-value> </context-param> ...
|
<context-param>
是在各个具体的<servlet>
元素之外的,同样可以设置多个<context-param>
。在任意具体的Servlet中,通过调用ServletContext
对象,就可以利用配置信息:
1 2
| ServletContext context = this.getServletContext(); String globalValue1 = context.getInitParameter("参数名");
|
通过ServletContext
的属性(attribute)实现不同Servlet之间的通信
事先不知道,无法预先配置的信息,应该如何共享?(比如将购物车中的商品共享给结算页面)
在具体的Serlvet中,通过ServletContext
对象的属性(attribute)设置希望共享的信息:
1 2 3 4
| ServletContext context = this.getServletContext(); context.setAttribute("属性名","属性值"); String attribute = (String) context.getAttribute("属性名"); context.removeAttribute("属性名");
|
读取外部资源配置文件信息
通过ServletContext
的方法读取。
getResource(“外部资源配置文件的路径”)
1 2 3 4 5 6 7
| ServletContext context = this.getServletContext(); URL url = context.getResource("外部资源配置文件的相对路径"); InputStream in = url.openStream();
|
getResourceAsStream(“外部资源配置文件的路径”)
1 2 3 4 5 6 7 8 9 10 11 12
| public class ServletDemo3 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Properties prop = new Properties(); prop.load(is); String username = prop.getProperty("username"); String passwd = prop.getProperty("passwd"); resp.getWriter().print(username + ": " + passwd); }
|
getRealPath(“外部资源配置文件的相对路径”)
获取外部资源配置文件的绝对路径
1
| String realPath = context.getRealPath("外部资源配置文件的相对路径");
|
HttpServletRequest类
常见应用
获取前端传递的参数
getParameter()
getParameterValues()
请求转发
请求转发就是将当前的HttpServletRequest
和HttpServletResponse
对象交给指定的web组件处理。对客户端来说,是一次请求,一次响应,浏览器的URL不变。
步骤:
- 获取请求转发对象
即获取RequestDispatcher
类的对象(由Servlet容器创建,封装由路径所标识的服务器资源)。
获取请求转发对象有两种方式:
- 通过
HTTPServletRequest
对象获取:
RequestDispatcher rd = request.getRequestDispatcher("绝对路径/相对路径");
- 通过
ServleContext
对象获取:
RequestDispatcher rd = this.getServletContext().getNamedDispatcher("servlet-name");
或者RequestDispatcher rd = this.getServletContext().getRequestDispatcher("绝对路径");
- 调用转发对象的
forward(HttpServletRequest req, HttpServletResponse resp)
方法
例子:
1 2 3 4 5 6 7 8 9 10
| public class ServletDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); context.getRequestDispatcher("/getInitParam").forward(req, resp); } }
|
HttpServletResponse类
向浏览器发送数据的方法
getOutputStream()
getWriter()
向浏览器发送响应头的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
|
常见应用
向浏览器输出消息
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext(); String username = (String) context.getAttribute("username");
resp.setContentType("text/html"); resp.getWriter().print("用户名:" + username); } }
|
下载文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class FileServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String realPath = "C:\\Users\\Hunter\\IdeaProjects\\javaweb-02-servlet\\response\\src\\main\\resources\\20180422 卡特迈国家公园和自然保护区里午睡的灰熊幼崽,阿拉斯加州 1920x1080.jpg"; System.out.println("下载文件的路径:" + realPath);
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8")); FileInputStream fis = new FileInputStream(realPath); BufferedInputStream bis = new BufferedInputStream(fis); ServletOutputStream sos = resp.getOutputStream(); byte[] bytes = new byte[1024]; int len = 0; while ((len = bis.read(bytes)) != -1) { sos.write(bytes, 0, len); } bis.close(); sos.close(); } }
|
验证码功能
实现方式:
- 前端实现
- 后端实现,需要用到java的图片类,产生一个图片
实现重定向
请求重定向就是通过HttpServletResponse
对象发送给客户端一个新的URL地址,让其重新请求。对客户端来说,是两次请求,两次响应。
请求重定向的方法:resp.sendRedirect("绝对路径");
,其中路径需要写明tomcat设置的application context前缀,可用req.getContextPath()
获取绝对路径前缀。