1.1、 Servlet简介
- Servlet是Sun公司开发的动态web的一门技术
- Sun公司在这些API中提供一个接口叫做:Servlet。如果想开发一个Servlet程序,只需要完成两个步骤
- 编写一个类,实现Servlet接口
- 把开发好的Java类部署到web服务器中。
1.2、编写一个Servlet程序
-
编写一个普通类
-
实现Servlet接口,继承HttpServlet
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.println("Hello,Servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
编写Servlet的映射
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <!--注册Servlet--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.servlet.HelloServlet</servlet-class> </servlet> <!--Servlet 的请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
-
配置Tomcat并启动
1.3、Mapping问题
-
一个Servlet可以指定一个映射路径
<!--Servlet 的请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
一个Servlet可以指定多个映射路径
<!--Servlet 的多个请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <!--Servlet 的多个请求路径2--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <!--Servlet 的多个请求路径3--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping>
-
一个Servlet可以指定通用映射路径
<!--Servlet 的指定通用请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
-
默认请求路径
<!--Servlet 的默认请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
-
指定一些后缀或者前缀路径
<!--Servlet 的自定义请求路径--> <!--注意:*前面不能加项目映射的路径,否则会导致运行不成功 如:/*.do--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
-
优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求
<!--模拟 404页面 Servlet配置--> <servlet> <servlet-name>error</servlet-name> <servlet-class>com.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
1.4、ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。
-
共享信息
在一个Servlet类中保存数据,另外一个Servlet中可以拿到信息
-
往ServletContext 存储信息
package com.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //往ServletContext 存储信息 public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); String username="张三"; servletContext.setAttribute("username",username); System.out.println("Hello"); } }
-
获取ServletContext 存储的信息
package com.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //获取ServletContext 存储的信息 public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); String username= (String) servletContext.getAttribute("username"); resp.setHeader("Content-type", "text/html;charset=UTF-8"); resp.getWriter().print("名字:"+username); } }
-
配置web.xml信息
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>getservlet</servlet-name> <servlet-class>com.servlet.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getservlet</servlet-name> <url-pattern>/getc</url-pattern> </servlet-mapping> </web-app>
-
测试结果图
-
-
读取资源文件
Properties
- 在java目录下创建properties
- 在resources目录下创建properties
package com.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ServletDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Properties prop=new Properties(); prop.load(resourceAsStream); String username=prop.getProperty("username"); String pwd=prop.getProperty("pwd"); resp.getWriter().print("username"+username); } }
<servlet> <servlet-name>sv1</servlet-name> <servlet-class>com.servlet.ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>sv1</servlet-name> <url-pattern>/sv1</url-pattern> </servlet-mapping>
1.5、HttpServletResponse
1、简介
web服务器接收到的客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest的对象和代表响应的一个HttpServletResponse
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
2、下载文件
- 获取需要下载的路径
- 下载的名称
- 设置下载类型
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取需要下载的路径
String realPath = "D:\\JAVA_Demo\\javaweb-servlet\\response\\target\\classes\\1.png";
System.out.println(realPath);
//2. 下载的名称
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
System.out.println(filename);
//3. 设置下载类型
//设置响应的消息头
resp.setContentType("text/html;charset=UTF-8");
//设置响应类型中包含文件附件 URLEncoder.encode 防止中文乱码
resp.setHeader("Content-Disposition", "attachment; " +
"filename="+ URLEncoder.encode(filename,"UTF-8"));
//4. 获取下载文件的输入流
FileInputStream inputStream=new FileInputStream(realPath);
//5. 创建缓冲区
int len=0;
byte[] buffer = new byte[1024];
//6. 获取OutputStream对象
ServletOutputStream out=resp.getOutputStream();
//7. 将FileOutputStream流写入到buffer缓冲区
while ((len=inputStream.read(buffer))>0)
{
out.write(buffer,0,len);
}
inputStream.close();
out.close();
}
}
3、验证码功能
-
web.xml添加Servlet设置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <servlet> <servlet-name>image</servlet-name> <servlet-class>com.servlet.ImageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>image</servlet-name> <url-pattern>/img</url-pattern> </servlet-mapping> </web-app>
-
编写验证码实现类
package com.servlet; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; public class ImageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //让浏览器5秒刷新 resp.setHeader("refresh","3"); //在内存中创建一个图片 BufferedImage bufferedImage = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB); //得到图片 Graphics2D g=(Graphics2D) bufferedImage.getGraphics();//笔 //设置图片的背景颜色 g.setColor(Color.white); g.fillRect(0,0,80,20); //给图片写数据 g.setColor(Color.BLUE); g.setFont(new Font(null,Font.BOLD,20)); g.drawString(makeNum(),0,20); //浏览器以图片的方式打开 resp.setContentType("image/jpeg"); //停止浏览器缓存 resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); //把图片写给浏览器 ImageIO.write(bufferedImage,"jpg",resp.getOutputStream()); } private String makeNum() { Random random = new Random(); StringBuffer sb=new StringBuffer(); String num= random.nextInt(9999999)+""; for (int i = 0; i < 7-num.length(); i++) { sb.append("0"); } num= sb.toString() + num; return num; } }
4、实现重定向
-
简介
一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向
-
实现
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <servlet> <servlet-name>image</servlet-name> <servlet-class>com.servlet.ImageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>image</servlet-name> <url-pattern>/img</url-pattern> </servlet-mapping> <servlet> <servlet-name>RedirectServlet</servlet-name> <servlet-class>com.servlet.RedirectServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RedirectServlet</servlet-name> <url-pattern>/red</url-pattern> </servlet-mapping> </web-app>
package com.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("/img"); //重定向 } }
-
模型登录并重定向新的页面
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <servlet> <servlet-name>RequestTest</servlet-name> <servlet-class>com.servlet.RequestTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>RequestTest</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>
package com.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RequestTest extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String pwd = req.getParameter("pwd"); resp.sendRedirect("/success.jsp"); } }
<html> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <body> <h2>Hello World!</h2> <%--提交的路径,需要找到项目的路径--%> <%--${pageContext.request.contextPath}代表当前的项目--%> <form action="${pageContext.request.contextPath}/login" method="get"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="pwd"><br> <input type="submit" name="but_submit" value="登录"> </form> </body> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>success</h1> </body> </html>
测试图
1.6、HttpServletRequest
-
简介
HttpServletRequest 代表客户端的请求,用户通过http协议访问服务器。Http请求中的所有信息都会封装到HttpServletRequest中,通过这个HttpServletRequest的方法,获取客户端的所有信息。
1、获取前端传递的参数、请求转发
重定向与转发的区别
相同点
- 页面实现跳转
不同点
- 请求转发,Url地址栏不会改变,状态码为307
- 重定向,Url地址栏发生改变,状态码为302
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>
登录
</h1>
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="pwd"><br>
<input type="submit" value="登录">
</form>
</div>
</body>
</html>
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
//通过请求转发
//这里的 /代表的当前的web应用
req.getRequestDispatcher("/success.jsp").forward(req,resp);
//解决乱码问题
resp.setCharacterEncoding("utf-8");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}