servlet学习

流程

servlet学习

JSP/Servlet

Tomcat

文件目录

---bin          启动、关闭的脚本文件
---conf			配置
  |---server.xml    核心文件  可修改端口、主机名称等  默认8080
---lib			依赖的jar包
---logs			日志
---webapps		发存放的网站

默认端口

tomcat:8080

mysql:3306

http:80

https:443

网站

文件结构
---webapps	Tomcat服务器的web目录
    -ROOT
    -xxxx   网站的目录名
    	|-WEB-INF
    	|	|-class		Java程序
        |   |-lib		web应用所依赖的jar包
        |   |-web.xml	网站配置文件
        |-index.html	默认首页
        |-static
        |   |-css
        |   |   |-style.css
        |   |-js
        |   |-img
        |-...

Http

Http请求

Request URL
Request Method:GET
Status Code:200 OK
Remote Address:14.215.177.39:443

Http响应

Cache-Control:private		缓存控制
Connection:Keep-Alive		连接
Content-Encoding:gzip		编码
Content-Type:text/html		类型
响应体
Accept
Accept-Encoding
Accept-Language
Cache-Control
Connection	
HOST
Refresh			定时刷新
Location		网页重定位
状态码

200

4xx: 资源不存在 4040

3xx:请求重定向

5xx: 服务器代码错误 500 502(网关错误)

Accept
Accept-Encoding
Accept-Language
Cache-Control
Connection				请求结束后是否保持连接
...

Maven

环境配置

M2_HOME 目录\bin

MAVEN_HOME 目录

镜像配置

<mirror>
	    <id>nexus-aliyun</id>
	    <mirrorOf>central</mirrorOf>
	    <name>Nexus aliyun</name>
    	<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

本地仓库

<localRepository>D:\environment\Maven\apache-maven-3.8.3\maven-repo</localRepository>

IDEA中使用Maven

  1. 新建Maven项目 (选用模板)
  2. 注意 仓库和配置文件
  3. IDEA中查看 仓库和配置
  4. 等待项目初始化
  5. 这里就Ok了

servlet学习

创建普通Maven项目

  1. 新建Maven 不选用模板
  2. 同上

servlet学习

在IDEA中标记源码功能

servlet学习

servlet学习

在IDEA中配置tomcat

servlet学习

servlet学习

pom文件

pom.xml是Maven的核心配置文件

servlet学习

由于Maven约定大于配置,自己写的配置会有导不出的问题出现

解决方法:在pom中添加resources节点

<build>
      <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>**/*.properties</exclude>
                <exclude>**/*.xml</exclude>
             </excludes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

web.xml

用tomcat里的web.xml配置即可

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                      https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0"
         metadata-complete="true">
</web-app>

Servlet

继承HttpServlet 或 GenericServlet

前者是后者的继承

HelloServlet

  1. 构建一个普通的Maven项目,删除src目录,之后要建项目就可以在该目录下建module,这个空项目就是Maven的主项目
  2. Maven父子项目的关系

父项目中有

<modules>
    <module>servlet-01</module>
</modules>

子项目中有

<parent>
    <artifactId>xxxx</artifactId>
    <groupId>com.kuang</groupId>
    <version>1.0sSNAPSHOT</>
</parent>

相当于son extents parent

  1. Maven环境优化
  • ​ 修改web.xml为最新的
  • ​ 将maven的结构搭建完整(java和recourses包)
  1. 编写一个servlet程序
  • ​ 建一个普通类
  • ​ 继承HttpServlet、
  1. 重写自己需要的方法
  • ​ doGet
  • ​ doPost
  • ​ doDelete
  • ​ .........................
  1. 编写Servlet的映射
  2. 运行

Bug

servlet学习

原因:Tomcat10之后包名不再是"javax.servlet”,则是改为"jakarta.servlet"

解决办法:

第一种解决办法:Tomcat版本改为10以下的版本

第二种解决办法:“javax.servlet”改为"jakarta.servlet”

<dependency>
  <groupId>jakarta.servlet.jsp</groupId>
  <artifactId>jakarta.servlet.jsp-api</artifactId>
  <version>3.0.0</version>
</dependency>
<dependency>
  <groupId>jakarta.servlet</groupId>
  <artifactId>jakarta.servlet-api</artifactId>
  <version>5.0.0</version>
</dependency>

最后修改导入的包名

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

servlet原理

servlet学习

Mapping映射

url pattern 不是后缀行一定要加/

<servlet>
    <servlet-name>Hello,world</servlet-name>
    <servlet-class>com.learn.yys.Hello</servlet-class>
</servlet>
  1. 一个servlet对应一个映射路径
<servlet-mapping>
<servlet-name>Hello,world</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
  1. 一个servlet对应多个映射路径
<servlet-mapping>
<servlet-name>Hello,world</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>Hello,world</servlet-name>
<url-pattern>/hellow2</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>Hello,world</servlet-name>
<url-pattern>/hello13</url-pattern>
</servlet-mapping>
  1. 一个servlet可以指用映射路径
<servlet-mapping>
<servlet-name>Hello,world</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
  1. 默认请求路径

    相当于index.html的地位 让Hello的Java成了index.html

<servlet-mapping>
<servlet-name>Hello,world</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
  1. 指定 后缀 等
<servlet-mapping>
<servlet-name>Hello,world</servlet-name>
<url-pattern>*.yys</url-pattern>  //默认访问以.yys结尾的路径  注意*前不能加项目映射路径
//   hello/sdf.yys 的访问也是默认走这个路径
</servlet-mapping>
  1. 优先级

指定大于默认

可以用来写404等

package com.learn.yys;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

public class ErrorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.write("<h1>404 error</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
<servlet>
    <servlet-name>404</servlet-name>
    <servlet-class>com.learn.yys.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>404</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

ServletContext

servlet学习

web容器再启动的时候,会为每个web程序都创建一个对应的servletContext对象,它代表了当前的web应用

作用:

  1. 共享数据

在这个Servlet中保存的数据,可以在另一个servlet中拿到

servlet学习

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext servletContext = this.getServletContext();
    String name = "yys";
    servletContext.setAttribute("name",name);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext servletContext = this.getServletContext();
    String name = (String) servletContext.getAttribute("name");
    resp.getWriter().println(name);
}
  1. 获取初始化参数
<context-param>
    <param-name>database</param-name>
    <param-value>jdbc:mysql//localhost:3306/mybatis</param-value>
</context-param>

<servlet>
    <servlet-name>getParam</servlet-name>
    <servlet-class>GetParam</servlet-class>
</servlet>
<servlet-mapping>
     <servlet-name>getParam</servlet-name>
     <url-pattern>/get_param</url-pattern>
</servlet-mapping>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext servletContext = this.getServletContext();
    String database = servletContext.getInitParameter("database");
    resp.getWriter().println(database);
}
  1. 请求转发
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
//        RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/get_param");//转发请求路径
//        requestDispatcher.forward(req,resp);//调用forward实现转发
        servletContext.getRequestDispatcher("/get_param").forward(req,resp);
    }
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>Dispatcher</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/dispatcher</url-pattern>
</servlet-mapping>
  1. 读取资源文件

java包和recourses包的内容打包后都在classes目录下

称之为classpath

servlet学习

这里会有资源导出的问题 在java包内的properties可能导不出

需要在pom里添加配置

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    InputStream inputStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
    Properties properties = new Properties();
    properties.load(inputStream);
    String name = properties.getProperty("name");
    String password = properties.getProperty("password");
    resp.getWriter().println(name+":"+password);


}

HttpServletResponse

负责向浏览器发送数据的方法

public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;

负责向浏览器发送响应头的方法

各种set和add

常见应用

  1. 向浏览器输出信息

  2. 下载文件

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 获取文件路径
        String realPath = "E:\\code\\JavaWeb\\MyJavaWeb\\lesson2\\target\\lesson2-1.0-SNAPSHOT\\WEB-INF\\classes\\db.properties";
        System.out.println("下载文件的路径:"+realPath);
        //2. 下载的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("//") + 1);
        //3. 设置让浏览器支持下载       中文文件名URLEncoder
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
        //4. 获取下载文件的输入流
        FileInputStream fileInputStream = new FileInputStream(realPath);
        //5. 创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        //6. 获取OutputStream对象
        ServletOutputStream outputStream = resp.getOutputStream();
        //7. 将FileOutputStream流写入buffer缓冲区,使用OutputStream将缓冲区中数据输出到客户端
        while ((len = fileInputStream.read(buffer))>0){
            outputStream.write(buffer,0,len);
        }
        outputStream.close();
        fileInputStream.close();
    }
    

验证码

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //浏览器3秒刷新一次
    resp.setHeader("refresh","3");
    //在内存中创建图片
    BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
    //得到图片
    Graphics2D graphics2D = (Graphics2D)bufferedImage.getGraphics();//笔
    //设置图片背景颜色
    graphics2D.setColor(Color.WHITE);
    graphics2D.fillRect(0,0,80,20);
    //给图片写数据
    graphics2D.setColor(Color.BLACK);
    graphics2D.setFont(new Font(null,Font.BOLD,20));
    graphics2D.drawString(makeNum(),0,20);

    //告诉浏览器 请求用图片方式打开
    resp.setContentType("image/jpg");
    //网站存在缓存,让浏览器不缓存
    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();
    String num = random.nextInt(9999999)+"";
    StringBuffer sb =  new StringBuffer();
    for (int i = 0;i<7-num.length();i++)
        sb.append("0");
    num = sb.append(num).toString();
    return num;
}

重定向

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.sendRedirect("/lesson2_war/image");
}
注意完整的url

HttpServletRequest

  1. 获取前端传递的参数
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.setCharacterEncoding("utf-8");
    resp.setCharacterEncoding("utf-8");
    PrintWriter writer = resp.getWriter();
    String username = req.getParameter("username");
    String pwd = req.getParameter("password");
    writer.println(username+":"+pwd);
    writer.println("-------------------");
    Map<String, String[]> parameterMap = req.getParameterMap();
    for (Map.Entry<String, String[]> stringEntry : parameterMap.entrySet()) {
        writer.println(stringEntry.getKey()+":"+ Arrays.toString(stringEntry.getValue()));
    }
    Enumeration<String> parameterNames = req.getParameterNames();
    while (parameterNames.hasMoreElements())
        writer.println(parameterNames.nextElement());
    writer.println("-------------------");
    String[] hobbies = req.getParameterValues("hobbies");
    writer.println(Arrays.toString(hobbies));
}
  1. 请求转发
req.getRequestDispatcher("/success.jsp").forward(req,resp);  /代表当前项目目录

服务端给客户端一个信件,客户端下次访问服务端带上信件即可

客户端技术(响应,请求)

Cookie类的各种方法

注意中文字符问题 URLEncoder

Session

服务端登记来过,下次来时服务端匹配客户端

服务端技术,保存会话信息

  • 服务器会给每个用户(浏览器)创建一个session对象
  • 一个session独占一个浏览器,只要浏览器没关,session就存在

Session类的各种方法

手动注销

session.invalidate();

自动注销在xml中设置

<session-config>
	<session-timeout>15</session-timeout>//这里是min不是s
</session-config>
上一篇:c语言笔试之经典好题


下一篇:TypeScript 和 JavaScript对比