柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

  • JavaWeb

    • Tomcat
    • JavaWeb Servlet
      • Servlet API
        • Servlet
        • GenericServlet
        • HttpServlet
        • ServletContext
      • Servlet 应用
      • Servlet 工作原理
      • Servlet 生命周期
      • Request 请求
      • Response 响应
        • 响应图片
      • Session 会话
      • Servlet 初始化参数
      • Servlet 注解
      • Servlet 下载
    • JSP
    • 过滤监听器
    • 会话跟踪
    • MVC设计模式
    • Ajax
    • JSON
    • JspSmartUpload应用
  • 拓展技术

  • 框架技术

  • 数据库

  • 数据结构

  • Spring

  • SpringMVC

  • SpringBoot

  • SpringClound

  • Ruoyi-Vue-Plus

  • 后端
  • JavaWeb
柏竹
2020-02-18
目录

JavaWeb Servlet

# Servlet

Servlet是在Web服务器运行的Java程序,主要负责与客户端数据交互,生成动态的Web内容。通常 通过HTTP 进行 接收 和 响应 来自客户端的请求!

工作步骤:

  1. 服务器 启动Servlet
  2. 客户端 发送请求 至 服务器
  3. 服务器 调用Servlet,根据 客户端 请求内容 传给服务器
  4. 服务器 响应返回 客户端

# Servlet API

点击查看文档 (opens new window)

# Servlet

implements Servlet javax.servlet

用于 接收请求 与 响应请求 ,服务器必须实现的方法

返回 抽象方法 说明
void ==init()== 构造服务器
void ==service()== 服务器 响应请求
void ==destroy()== 移出 服务器 视为垃圾
ServletConfig ==getServletConfig()== 获取 服务器对象
String ==getServletInfo()== 获取 有关服务器的信息

# GenericServlet

class abstract GenericServlet javax.servlet

GenericServlet类 实现 Servlet接口 用于Web的 HTTP Servlet 服务项

返回 方法 说明
Enumeration ==getInitParameterNames()== 获取 指定参数名的对象
Enumeration ==getServletName()== 获取 服务名
ServletContext ==getServletContext()== 获取 全局对象

# HttpServlet

class abstract HttpServlet javax.servlet.http

HttpServlet 继承 GenericServlet类 处理 http请求数据

返回 方法 说明
void ==doGet()== 处理GET请求
void ==doPost()== 处理POST请求
void ==doPut()== 处理PUT请求
··· ... ...(更多自查文档)

# ServletContext

implements ServletContext

javax.servlet Interface ServletContext

点击对象方法 (opens new window)

用于与其他 servlet容器 通信的方法

获取方式在请求的方法体里

  • ==this.getServletContext()==
  • ==HttpServletRequest.getServletContext()==

存取值常用方法

返回 方法 说明
void setAttribute(String key,Object value) 向上下域 存键值
Object getAttribute(String key) 从上下域 取指定键的值
void removeAttribute(String key) 删除上下文 指定键的值

# Servlet 应用

  1. 在 web 创建 index.html ,模拟客户端请求发送
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>!!!</title>
</head>
<body>
    <h1>No.1 Servlet应用</h1>
    <a href="test">get请求测试</a>
    <form action="test" method="post">
        <input type="submit" value="post-test">
    </form>
</body>
</html>
  1. 创建实现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;

public class LoginServlet extends HttpServlet {
    
    /*
    * HttpServletRequest:请求对象
    * HttpServletResponse:响应对象
    * */
    
    //处理 get 请求
    @Override
    protected void doGet(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get-------");
        System.out.println("req : " + req);
        System.out.println("resp : " + resp);
    }
    
    //处理 post 请求
    @Override
    protected void doPost(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post-------");
        System.out.println("req : " + req);
        System.out.println("resp : " + resp);
    }
    
}
  1. 在 ../web/WEB-INF/web.xml 文档配置映射关系 在 <web-app> 添加映射关系
<servlet>
    <!-- ⾃定义名称 -->
    <servlet-name>No1</servlet-name>
    <!-- 
	处理请求的类的完整路径
	LoginServlet类在src根路径里
	 -->
    <servlet-class>LoginServlet</servlet-class>
</servlet>
<!-- mapping 表示映射 -->
<servlet-mapping>
    <!-- ⾃定义名称 -->
    <servlet-name>No1</servlet-name>
    <!-- 请求名 -->
    <url-pattern>/test</url-pattern>
</servlet-mapping>

标签执行顺序:

  1. 客户端 请求
  2. 进入 web.xml 匹配数据
  3. <servlet-mapping> 里的 <url-pattern> 标签 内容 与 请求名 进行匹配
  4. 匹配成功后 进行以下匹配 (映射标签) <servlet-mapping> 里的 <servlet-name> 标签 内容 与 <servlet> 里的 <servlet-name> 标签 内容
  5. 匹配成功后 进行以下匹配 (处理类路径) <servlet> 里的 <servlet-class> 标签 内容 与 src内的路径匹配
  1. 启动,打开 地址: (以下两个测试) http://localhost:8080/工程名/访问服务器的路径 http://localhost:8080

# Servlet 工作原理

  1. Servlet容器 将Servlet类载入内存 , 实例调用它具体方法。一个Web应用一个Servlet
  2. 调用Servlet的Service()方法 ServletRequest对象 (请求对象) 和 ServletResponse对象 (响应对象) 都是由 Servlet容器 封装好的,直接调用即可
  3. 每个Servlet都有一个封装Servlet配置的 ServletConfig对象

# Servlet 生命周期

  1. 实例化(使用构造方法创建对象)
  2. 初始化 init()方法
  3. 服务 service()方法
  4. 销毁 destroy()方法

init方法 将会主要完成以下工作:

  1. 创建用于解析 xml 配置文件的 contextDigester 对象
  2. 读取默认 context.xml 配置文件,如果存在解析它
  3. 读取默认 Host 配置文件,如果存在解析它
  4. 读取默认 Context 自身的配置文件,如果存在解析它
  5. 设置 Context 的 DocBase

注意:

  1. 当客户端发送请求,如果 存在servlet对象无需创建,否则新建servlet对象
  2. 第二次请求时,会判断对象是否存在,但不会执执行init()方法,而直接执行service()方法
  3. 相应的请求方式,会对应 service方法里的处理方式

# Request 请求

HttpServletRequest表示Http环境中的Servlet请求。(扩展了ServletRequest接口)

点击更多Servlet请求方法 (opens new window)

返回 常用方法 说明
String ==getParameter(String name)== 获取 表单指定名称 组件的值
String[] ==getParameterValues(String name)== 获取 表单指定名称 组件的多个值
void ==setCharacterEncoding(String env)== 设置 请求的编码类型(针对Post请求)
RequestDispatcher ==getRequestDispatcher(String url)== 跳转 指定页面路径
void ==setAttribute(String key , String value)== 存储请求属性
Object ==getAttribute(String key)== 获取 指定属性的返回值
String ==getRequestURI()== 获取 url

请求方式:

  • 通过表单 get/post 提交

  • 通过 a标签 发送数据

    <a href="提交名?key1=value&key2=vlaue..">提交</a>
    <a href="/test?name=sans&age=12">提交</a>
    
  • 通过地址栏直接拼接-get请求

  • js提交数据-get请求

乱码处理:

  • post请求转编码 setCharacterEncoding("UTF-8");

  • get请求 转编码 (方法1)

    //针对于get提交时中⽂乱码
    String s=new String(变量名.getBytes("ISO-8859-1"),"UTF-8");
    String s=new String(request.getParameter("key").getBytes("ISO-8859-1"),"GBK");
    
  • get请求 转编码 (方法2) 在Tomcat目录 /conf/server.xml 设置字符集

    <Connector port="8080" protocol="HTTP/1.1" 
     connectionTimeout="20000"
     redirectPort="8443" URIEncoding="UTF-8" />
    

get和post区别:

get请求: 该请求会附加在URL之后,从 ? 开始以 & 分割变量和属性。url采用的是ASCLL编码。

post请求: 该请求数据置放在HTTP请求包的包体中进行传输数据。

数据传输大小 get会受到url的长度限制,而post不会

安全性 提交/进入 时,get会在url后面显示,而post不会

实例:

html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>!!!</title>
</head>
<body>
    <a href="requestTest?click=true&summary=用户点击了超链接">超链接测试</a>
    <form action="requestTest" method="post">
        uname:<input type="text" name="username"><br>
        upassword:<input type="password" name="userpassword"><br>
        sex:
        <input type="radio" name="sex" value="man">男
        <input type="radio" name="sex" value="woman">女
        <br>
        hobby:
        <input type="checkbox" name="hobby" value="basketball">篮球
        <input type="checkbox" name="hobby" value="football">足球
        <input type="checkbox" name="hobby" value="tennis">网球
        <br>
        <input type="submit">
    </form>
</body>
</html>

Java获取

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 MyRequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Get=========");
        System.out.println("超链接点击了?"+req.getParameter("click"));
        System.out.println("摘要:"+req.getParameter("summary"));
    }
    
    @Override
    protected void doPost(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Post=========");
        //解决乱码
        req.setCharacterEncoding("utf-8");
        
        String name = req.getParameter("username");
        String password = req.getParameter("userpassword");
        String sex = req.getParameter("sex");
        String[] hobbys = req.getParameterValues("hobby");

        System.out.println("UserName:"+name);
        System.out.println("UserPassword:"+ password);
        System.out.println("sex:"+ sex);
        if (hobbys != null || hobbys.length != 0){
            System.out.println("hobby:");
            for (String tmp : hobbys) {
                System.out.println(tmp);
            }
        }
        
        //存值
        req.setAttribute("username",name);
        req.setAttribute("userpassword",password);
        
        //取值
        System.out.println("取值测试:");
        System.out.println(req.getAttribute("username"));
        
        //跳转页面 (提交跳转的页面 在web文件夹下subTest.html)
        req.getRequestDispatcher("/subTest.html").forward(req,resp);
    }
}

# Response 响应

HttpServletResponse 表示 Servlet响应,继承了ServletResponse接口,专门用来封装HTTP响应消息。

点击更多Servlet响应方法 (opens new window)

返回 常用方法 说明
void ==addCookie(Cookie cookie)== 指定 cookie添加到响应中
void ==sendRedirect(String location)== 指定 重定向URL位置(页面跳转)
PrintWriter ==getWriter()== 获取 可以给前端输出的字符流对象
void ==setContentType(String type)== 设置 响应的内容类型

重定向与转发的区别

  • 重定向 会改变地址,requset存储的数据会丢失 转发 时地址会显示请求页面的地址,保存了页面的数据
  • 重定向 两次请求 两次响应;转发 一次请求 一次响应
  • js 跳转页面,也会丢失 requset存储的数据

# 响应图片

以流的形式响应图片

实现方案:

  1. 使用FileChannel的方法
  2. 使用普通的io,fileinputstream->byte[]->response.outputstream
  3. 使用ImageIO的read和write方法实现
// 方式1
@Override
protected void doGet(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
    File file = new File("C:\\Users\\admin\\Desktop\\ceshi.jpg");
    try (FileInputStream fis = new FileInputStream(file)) {
        response.setContentType("image/png");
        fis.getChannel().
            transferTo(0,fis.available(),Channels.newChannel(response.getOutputStream()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

// 方式2
@Override
protected void doGet(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
    File file = new File("C:\\Users\\admin\\Desktop\\ceshi.jpg");
    try(FileInputStream fis = new FileInputStream(file)) {
        response.setContentType("image/png");
        byte[] bytes = new byte[fis.available()];
        fis.read(bytes);
        response.getOutputStream().write(bytes);
    }catch (Exception e){
        e.printStackTrace();
    }
}

// 方式3
@Override
protected void doGet(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
    File file = new File("C:\\Users\\admin\\Desktop\\ceshi.jpg");
    try {
        BufferedImage image = ImageIO.read(file);
        response.setContentType("image/png");
        OutputStream os = response.getOutputStream();
        ImageIO.write(image, "png", os);
        os.flush();
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

# Session 会话

session是服务器端使用的一种记录客户端状态的机制。(是ServletRequest的扩展) sessinon可有多个页面、多个request(请求),重定向也不会丢失数据。 当浏览器访问Web服务器时,Servlet容器就会创建一个Session对象和ID属性,当客户端后续访问服务器时,只要将ID标识号传递给服务器,服务器就能判断该请求是哪个客户端发送的,从而选择与之对应的Session对象为其服务。

更多ServletRequest方法 (opens new window) 更多HttpServletRequest方法 (opens new window) 更多HttpSession方法 (opens new window)

返回 常用方法 说明
HttpSession ==getSession()== 获取 请求的Session对象
void ==setAttribute(String key , Object value)== 以key/value存储属性值
Object ==getAttribute(String key)== 获取 指定key的属性值,没有则null
void ==invalidate()== 设置 session 无效,取消任何会话的对象
String ==getid()== 获取 当前 会话ID标识号
void ==setMaxInactiveInterval(int interval)== 设置 会话有效时长 ,超出时长则无效会话(单位:秒)
void ==removeAttribute(String key)== 从此会话 删除 指定key的值(置为null)

会话有效时长:

  1. setMaxInactiveInterval(int second) //指定秒数有效

  2. 编辑 web.xml

    <session-config>
     	<session-timeout>10</session-timeout>//单位:分钟
     </session-config> 
    

session失效方式:

  1. invalidate()
  2. removeAttribute("key");
  3. 直接关闭浏览器

# Servlet 初始化参数

在 web.xml 中配置 Servlet 时,可以配置初始化参数 Servlet可通过 ServletConfig接口 提供的方法来获取这些参数

servlet局部参数配置

在 web.xml 中对应的 servlet 添加 init-param属性(获取参数仅限于配置的servlet)

<init-param>
       <param-name>key</param-name>
       <param-value>value</param-value>
</init-param>

servlet全局部参数配置

在 web.xml 中添加 context-param属性 (全部servlet都可获取)

<context-param>
        <param-name>key</param-name>
        <param-value>value</param-value>
 </context-param>

获取数据

  1. 请求 -> init() -> ... servlet中 重写init()方法,通过以下代码获取 (全局和局部获取方式不一样)

    @Override
    public void init(ServletConfig config) throws ServletException {
        //匹配指定name 获取 对应的值
        //局部
        String vlaue = config.getInitParameter("key") );
        //全局
        String vlaue2 = config.getServletContext().getInitParameter("allKey") );
    }
    
  2. 请求 -> init() -> servlet() -> doGet()/doPost() -> ...

    //超链接响应获取
    @Override
    protected void doGet(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
        //局部
        String vlaue = this.getInitParameter("key");
        //全局
        String vlaue2 = this.getInitParameter("allKey");
        String vlaue3 = this.getServletContext().getInitParameter("allKey");
    }
    

注意: 不同的获取方式不能共存!!!

# Servlet 注解

注解 提供的信息,让开发更便捷易懂

属性 类型 必须 说明
asyncSupported boolean F Servlet是否支持异步操作
displayName String F Servlet显示名称
initParams webInitParam[] F 配置初始化参数
loadOnStartup int F Servlet 的优先级 加载(越小越早)
name String F 指定Servlet名称
urlPatterns/value String[] T 两个属性作用相同,指定处理的url

urlPatterns匹配说明

完全匹配 /test/userList.action 匹配绝对路径的请求

路径匹配 /test/* 匹配test路径下的所有请求

扩展名匹配 *.action 匹配后缀为action 结尾的请求

注意:

  • 如果当前Servlet注解了就无需再配置 web.xml
  • name若不指定值,则默认以类名为name
  • urlPatterns路径分割不需有斜杠 /
  • urlPatterns可映射多个路径
@WebServlet(
        name = "No.6",
        //完全路径;全局路径匹配;扩展名匹配
        //   /test/no1/index.css
        //   /test/*    ;   /test/no1/*
        //   *.css
        
        urlPatterns = "/test/no1/*",
        initParams = {
                @WebInitParam(name = "name",value = "zhangsan")
        },
        loadOnStartup = 1
)
public class AnnotationTest extends HttpServlet {
    ···
}

# Servlet 下载

如果用户需要通过 链接进行下载,可通过得到的请求进行响应输出,从而达到下载的效果

大致步骤:

  1. 通过 在请求中的属性 获取指定下载的文件名
  2. 获取 项目的下载虚拟路径 ==ServletContext.getRealPath(<web根目录开始找下载文件夹路径>)==
  3. 获取文件输入流 (拼接获取指定的文件流 (filename步骤1获取的属性值) ==new FileInputStream(path + filename);==
  4. 设置文件名解决汉字不能 。一定要用 iso8859-1 编码集(用于响应头拼接 ==new String(filename.getBytes(),"iso8859-1");==
  5. 设置响应头 ==resp.setHeader("content-disposition","attachment;filename="+filename);==
  6. 获取 响应输出流
  7. 读写输出至浏览器
  8. 关闭 输入、输出 流

示例:

下载的文件夹在根目录中的 files 文件夹 里

html

<body>
    <h3>超链接下载方式</h3>
    <div>
        <a href="files/file.txt">文本文件</a>
        <a href="files/file.jpg">图片文件</a>
        <a href="files/file.zip">压缩文件</a>
    </div>
    
    <h3>手动编码下载方式</h3>
    <div>
        <a href="/download?fileName=file.txt">文本文件</a>
        <a href="/download?fileName=file.jpg">图片文件</a>
        <a href="/download?fileName=file.zip">压缩文件</a>
    </div>
</body>

java

@WebSevlet("/download/*")

@Override
protected void doPost(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
    
    String filename = req.getParameter("fileName");
    String path = req.getServletContext().getRealPath("/files/");
    
    InputStream in = new FileInputStream(path + filename);
    // 对汉字进行编码(因 浏览器会 识别 iso8859-1
    filename = new String(filename.getBytes(),"iso8859-1");
    // 设置响应头
    resp.setHeader("content-disposition","attachment;filename="+filename);
    OutputStream out = resp.getOutputStream();
    byte[] bs = new byte[1024 * 8];
    int len = 0;
    while ((len = in.read(bs)) != -1) {
        out.write(bs,0,len);
    }
    in.close();
    out.close();
}
#Jsp#servlet
上次更新: 2023/03/12, 00:43:49

← Tomcat JSP→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式