Servlet
-
开发动态web的一门技术
-
API 提供接口 servlet 二个步骤开发servlet程序
-
编写一个类实现servlet接口
-
把开发号的java类部署到web服务器中
-
实现了servlet接口的java程序叫做 servlet
Maven Servlet 和 jsp 依赖
<dependencies> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.2.1</version> <scope>provided</scope> </dependency> </dependencies>
如何使用
-
构建一个Maven项目 删除src 在里面建立Moudel 空的工程就时Maven的主工程
-
关于Maven 父子类的理解
-
在父项目中有
<modules> <module>Servlet01</module> </modules>
-
子项目里有 idea 有时候会消失 手动加上即可
<parent> <artifactId>JavaWeb</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent>
-
-
Maven 环境优化
-
web.xml为最新的
<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"> </web-app>
-
将maven的结构搭建完整
-
-
编写一个servlet
-
编写一个普通类
-
实现servlet接口 继承HttpServlet
package com.chi.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.PrintWriter; public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.print("Hello,Servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
-
-
编写Servlet的映射
<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.chi.Servlet.HelloServlet</servlet-class> </servlet> <--!-->com.chi.Servlet.HelloServlet 是java代码路径</--!--> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/Hello</url-pattern> </servlet-mapping> <--!-->HelloServlet是于上面匹配即可 /Hello是打开指定这个网页时的名字 一定不要忘了斜杠</--!-->
-
配置Tomcat
-
启动测试
servlet 原理
Mapping 问题
-
一个Servlet 可以一处理一个映射路径
-
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/Hello</url-pattern> </servlet-mapping>
-
-
一个Servlet 可以处理多个映射路径
-
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/Hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/Hello1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/Hello2</url-pattern> </servlet-mapping>
-
-
一个Servlet 可以只等通用映射路径
-
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/Hello/*</url-pattern> </servlet-mapping>
-
-
指定一些后缀或者前缀等等
-
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>*.chi</url-pattern> </servlet-mapping> <!--只要以chi结尾就可以进入-->
-
-
默认请求路径
-
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <!--少用-->
-
-
优先级问题
-
指定类固有的映射的优先级最高,如果没有在去找默认的处理请求了
-
ServletContext
web 容器在启动的时候,它会为每个web程序都创建一个servletContext对象来代表web应用
共享数据
我在这个servlet中保存的东西可以在别的servlet中使用
package com.chi.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; //数据放入web容器 public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("Hello"); ServletContext servletContext = this.getServletContext(); String username = "帆船"; servletContext.setAttribute("username",username); //一个数据保存在了web容器里 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
package com.chi.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; // 取出来 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.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); resp.getWriter().print(username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }//在web.xml配置
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.chi.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>getc</servlet-name> <servlet-class>com.chi.servlet.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getc</servlet-name> <url-pattern>/getc</url-pattern> </servlet-mapping>
获取初始数据
<context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
package com.chi.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; public class ServletDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext=this.getServletContext(); String url =servletContext.getInitParameter("url"); resp.getWriter().print(url); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }//在web.xml配置
请求转发
package com.chi.servlet; import javax.servlet.RequestDispatcher; 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; public class ServletDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("sd4"); ServletContext servletContext=this.getServletContext(); RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/gp"); //请求转发 requestDispatcher.forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } } //在web.xml配置
读取资源文件
properties
-
在java目录下resource 下创建properties 文件
在运行时所有的包都被打包到了一个路径下 target 里 在target里面找到classpath 用一个流来读取
username=root password=123456
package com.chi.servlet; import javax.servlet.RequestDispatcher; 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; import java.io.InputStream; import java.util.Properties; public class ServletDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is =this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Properties properies =new Properties(); properies.load(is); String username = properies.getProperty("username"); String password = properies.getProperty("password"); resp.getWriter().print(username+":"+password); is.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } } //在web.xml配置
HttpServletResponse
web 服务器接收到客户端的Http请求, 分别创建一个代表请求的HttpServletRequest 对象和 代表响应的HttpServletResponse 对象
-
如果需要获取客户端请求过来的参数:找HttpServletRequest
-
如果需要客户端响应一些信息:HttpServletResponse
向浏览器发送数据的方法
public interface ServletResponse { ServletOutputStream getOutputStream() throws IOException; PrintWriter getWriter() throws IOException; }
向浏览器发送响应头的方法
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);
常用应用
下载文件
-
向浏览器输出消息
-
下载文件
-
获取下载文件的路径
-
下载的文件名
-
让浏览器能够支持我们需要下载的东西
-
获取下载文件的输入流
-
创建缓冲区
-
获取OutputStream对象
-
将FileOutputStream写入缓冲区buffer
-
OutputStream将缓冲区的数据输出到客户端
-
package com.chi.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; public class Response extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //- 获取下载文件的路径 String realPath = "D:\\Learning\\JavaWeb\\Response\\target\\classes\\1.png"; System.out.println("下载路径: "+ realPath); //- 下载的文件名 String fileName =realPath.substring(realPath.lastIndexOf("\\")+1); //- 让浏览器能够支持我们需要下载的东西 resp.setHeader("Content-Disposition","attachment;fileName="+fileName); //- 获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); //- 创建缓冲区 int len =0; byte[] buffer = new byte[1024]; //- 获取OutputStream对象 ServletOutputStream out = resp.getOutputStream(); //- 将FileOutputStream写入缓冲区buffer //- OutputStream将缓冲区的数据输出到客户端 while((len=in.read(buffer))>0){ out.write(buffer,0,len); } out.close(); in.close(); } //别忘了配置web.xml @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
验证码
验证码怎么来:
-
前端实现
-
后端实现,需要使用java的一个图片类,生产一个图片
package com.chi.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,30,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-chache"); resp.setHeader("Pragma","no-chache"); //把图片写给浏览器 ImageIO.write(bufferedImage,"jpeg",resp.getOutputStream()); } private String makeNum(){ Random number = new Random(); String RandomNumber=number.nextInt(9999999)+""; StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < 7-RandomNumber.length(); i++) { stringBuffer.append("0"); } RandomNumber=stringBuffer.toString()+RandomNumber; return RandomNumber; } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
重定向
一个web 资源收到客户端请求和 他会通知客户端去访问另外一个web资源 这个过程叫做重定向
常见场景:
-
用户登录 :登录完成重定向
void sendRedirect(String var1) throws IOException;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // resp.setHeader("Loction","/redirect/img"); // resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); //下面一行等于上面两行 resp.sendRedirect("/redirect/img"); }
<html> <body> <h2>Hello World!</h2> <%--${pageContext.request.contextPath}当前项目--%> <form action="${pageContext.request.contextPath}/login" method="get"> UserName: <input type="text" name="username"><br> PassWord: <input type="password" name="password"><br> <input type="submit"> </form> </body </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Success!!!!</h1> </body> </html>
package com.chi.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 ResquestTest extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //处理请求 String name =req.getParameter("username"); String password = req.getParameter("password"); System.out.println(name+" : "+password); //重定向 resp.sendRedirect("success.jsp"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }//不要忘记配置 web.xml
<servlet> <servlet-name>request</servlet-name> <servlet-class>com.chi.Servlet.ResquestTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>request</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping>
HttppServeltRequest
HttppServeltRequest代表客户端的请求,用户通过Http协议访问服务器, http请求中的所有今昔会封装到HttppServeltRequest, 通过这个方法可以获得客户端所有的信息
req.getParameter(""); //单个 req.getParameterValues(""); //多个
package com.chi.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.util.Arrays; public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name =req.getParameter("username"); String password =req.getParameter("password"); String []hobby =req.getParameterValues("hobby"); System.out.println(name); System.out.println(password); System.out.println(Arrays.toString(hobby)); //转发请求 req.getRequestDispatcher("/success.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }