其他分享
首页 > 其他分享> > servlet学习

servlet学习

作者:互联网

流程

image-20211029205029187

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了

image-20211125215727264

创建普通Maven项目

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

image-20211125215750005

在IDEA中标记源码功能

image-20211125220401561

image-20211125220457689

在IDEA中配置tomcat

image-20211125220852282

image-20211125221442879

pom文件

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

image-20211125222602887

由于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环境优化
  1. 编写一个servlet程序
  1. 重写自己需要的方法
  1. 编写Servlet的映射
  2. 运行

Bug

image-20211126154454491

原因: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原理

image-20211201201537915

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

image-20220114135437375

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

作用:

  1. 共享数据

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

image-20220114140027135

@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

image-20220114154236512

这里会有资源导出的问题 在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.invalidate();

自动注销在xml中设置

<session-config>
	<session-timeout>15</session-timeout>//这里是min不是s
</session-config>

标签:jakarta,resp,req,HttpServletResponse,学习,IOException,servlet
来源: https://www.cnblogs.com/yeshenlougu/p/15813678.html