Servlet

Servlet简介
● Servlet就是sun公司开发动态web的一门技术
● Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需完成两个小步骤:
○ 1、编写一个类,实现Servlet接口
○ 2、把开发好的java类部署到web服务器中。
● 总结:把实现了Servlet接口的java程序叫做,Servlet
HelloServlet

  1. 构建普通的maven项目,删掉里面的src目录,以后就在这个项目里面建立Moudel;这个空的工程就是maven主工程。
  2. 父i项目的jar包子项目可以直接使用
  3. maven环境优化
    a. 修改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">
</web-app>

b. 将maven接口搭建完整

   <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
  1. 编写一个servlet程序
    a. 编写一个普通类
    b. 实现Servlet接口,这里直接继承HttpServlet
package cn.zhy.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;

/**
 * @author D_sir
 * @createDate 2023-03-07 13:21
 */
public class HelloServlet extends HttpServlet {
    //由于get和post只是请求实现的不同方式。可以相互调用,业务逻辑都一样
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入了doGet方法");
        PrintWriter writer = resp.getWriter();//响应流
        writer.print("Hello,servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
  1. 编写servlet的映射
    a. 为什么需要映射,我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以需要在web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径。
   <!--    注册servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>cn.zhy.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--    servlet请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

6、配置tomact
注意项目发布路径
7、启动调试
servlet原理
在这里插入图片描述

Mapping问题

● 1、一个Servlet可以指定一个映射路径
<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
● 2、一个Servlet可以指定多个映射路径
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
● 3、一个Servlet可以指定通用映射路径,所以路径都会请求
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

● 4、默认请求路径
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

● 5、指定一些后缀或者前缀
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

● 6、优先级问题,指定了的固有的映射路径优先级最高,如果找不到就会走默认的处理请求
ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,他代表了当前web应用
共享数据
○ 我在这个Servlet中 保存的数据,可以在另外一个servlet中拿到
在这里插入图片描述

package cn.zhy.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;

/**
 * @author D_sir
 * @createDate 2023-03-08 14:09
 */
public class HelloServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hekllo");
        /*this.getInitParameter()   初始化参数
        this.getServletConfig()     Servlet配置
        this.getServletContext()    Servlet上下文
        */
        ServletContext context = this.getServletContext();

        String username = "张三";//数据
        context.setAttribute("username", username);//将一个数据保存至ServletConext容器中名字为username 值为username
    }

}
package cn.zhy.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;

/**
 * @author D_sir
 * @createDate 2023-03-08 15:11
 */
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");//获取容器中的东西
        //解决乱码问题
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字" + username);

    }
}
hello cn.zhy.servlet.HelloServlet1 hello /hello getS cn.zhy.servlet.GetServlet getS /gets

测试访问,先访问hello,把东西放入容器访问gets才会有东西
获取初始化参数

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}
url jdbc:locahost:3306 gp cn.zhy.servlet.ServletDemp03 gp /gp

读取资源文件
Properties
在Java目录下新建properties文件
在resourse目录下新建properties文件
发现都被打包在同一个路径下:classes我,我们称这个路径为classpath

 <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
  @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properties = new Properties();
        properties.load(is);
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        resp.getWriter().print(username + "\n" + password);
    }

在resourse文件夹下创建db.properties文件
username=root
password=123123
注册

sd5 cn.zhy.servlet.PropertiesServlet sd5 /sd5

HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse对象;
如果要获取客户端请求过来的参数:找HttpServletRequest
如果要给客户端响应一些信息:找HttpservletResponse
常见应用
1、向浏览器输出东西
ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException;
● 2、下载文件
○ 1.要获取下载文件的路径
○ 2.下载的文件名是啥?
○ 3.设置想办法让浏览器能够支持下载我们需要的东西
○ 4.获取下载文件的输入流
○ 5.创建缓冲区
○ 6.获取OutputStream对象
○ 7.将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//  ○ 1.要获取下载文件的路径
        String realPath = "E:\\javacode\\JavaWeb\\javaweb-01-servlet\\respone\\target\\respone\\WEB-INF\\classes\\1.jpg";
        System.out.println("下载的文件路径:" + realPath);

//  ○ 2.下载的文件名是啥,获取下载的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);

//  ○ 3.设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则可能出现乱码
        resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
//  ○ 4.获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);

//  ○ 5.创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
//  ○ 6.获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();

//  ○ 7.将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer, 0, len);
        }
        in.close();
        out.close();

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

3、验证码功能
后端实现,需要用到java的图片类。生成一个图片

package cn.zhy.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;

/**
 * @author D_sir
 * @createDate 2023-03-08 19:57
 */
public class ImgServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、如何让浏览器3秒自动刷新一次
        resp.setHeader("refresh", "3");

        //2、在内存中创建一个图片
        BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics g = image.getGraphics();//这是一支笔可以修改图片属性
        //设置图片背景颜色
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, 80, 20);
        //给图片写数据
        g.setColor(Color.pink);
        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(image, "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.toString() + num;
        return num;
    }
}

4、重定向
在这里插入图片描述

B一个web资源收到客户端A请求后,B他会通知A客户端去访问另外一个web资源C,这个过程叫重定向
● 常见场景
○ 用户登录
方法

void sendRedirect(String var1) throws IOException;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*resp.setHeader("Location", "/r/img");
        resp.setStatus(302);*/
        resp.sendRedirect("/r/img");
    }

面试题,请你聊聊重定向和转发的区别?
相同点
页面都会实现跳转
不同点
请求转发的时候,url不会发生变化
重定向的时候,url地址栏会发生变化
HttpServletRequest
1、获取前端传递的数据

 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");
        //获取参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println("==================");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("====================");
        //通过请求转发  在请求时/就代表当前web目录了,因此不用写前缀,
        req.getRequestDispatcher("/success.jsp").forward(req, resp);
    }

面试题,请你聊聊重定向和转发的区别?
相同点
页面都会实现跳转
不同点
请求转发的时候,url不会发生变化 307
重定向的时候,url地址栏会发生变化 302
Cookie、Session
会话
● 会话: 用户打开了一个浏览器,点击了很少超链接,访问多个web资源,关闭浏览器,这个过程称为会话
保存会话的两种技术
cookie
● 客户端技术(响应,请求)

 Cookie[] cookies = req.getCookies();//这里返回数组,说明Cookie可能存在多个//获取cookie
cookie.getName()//获取cookie中的key
cookie.getValue()//获取cookie中的value
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");//新建一个cookie
cookie.setMaxAge(24 * 60 * 60);//设置cookie有效期
        resp.addCookie(cookie);//响应给客户端一个cookie
package cn.zhy.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

/**
 * @author D_sir
 * @createDate 2023-03-09 20:38
 */
//保存用户上次访问的时间
public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务器,告诉你,你来的时间,把这个时间封装成为一个信件,你下再来,我就知道你来了
        //解决中文乱码
        resp.setContentType("text/html");
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");

        PrintWriter out = resp.getWriter();
        //Cookie,服务器从客户端获取
        Cookie[] cookies = req.getCookies();//这里返回数组,说明Cookie可能存在多个//获取cookie
        //判断Cookie是否存在
        if (cookies != null) {
            //如果存在怎么办
            out.write("你上次一访问的时间时:");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if (cookie.getName().equals("lastLoginTime")) {


                    //获取cookie中的值
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());

                }
            }

        } else {
            out.write("这是您第一次访问");
        }
        //服务器给客户端响应一个cookie
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
        //设置cookie的有效期为1天
        cookie.setMaxAge(24 * 60 * 60);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

cookie:一般会保存在本地的用户目录下appdata;
一个网站cookie是否存在上限!聊聊细节问题
一个Cookie只能保存一个信息;
一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;. Cookie大小有限制4kb;
浏览器上限300个cookie
删除Cookie;
·不设置有效期,关闭浏览器,自动失效;
设置有效期时间为0;
编码解码
Cookie cookie = new Cookie(“name”, URLEncoder.encode(“张三”, “utf-8”));//编码
out.write(URLDecoder.decode(cookie.getValue(), “UTF-8”));//解码

session(重点)
● 服务器技术,利用这个技术可以保存用户的会话信息,我们可以把用户信息或数据防止secssion
● 什么是Session:
○ 服务器会给每个用户创建一个session对象
○ 一个session会独占一个浏览器,只要浏览器没有关闭,这个sessin就存在
○ 用户登录之后,整个网站都可以访问
session和cookie的区别
● Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
● Session把用户的数据写到用户独占Sessioon中,服务器中保存(保存重要的信息,减少服务器资源浪费)
● Session由服务器创建
使用场景
● 保存一个用户登录的信息
● 购物车信息
● 在整个网站中经常使用的数据,将他保存到session中
使用Session

package cn.zhy.servlet;

import cn.zhy.pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author D_sir
 * @createDate 2023-03-10 19:10
 */
public class SessionDeno01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        resp.setCharacterEncoding("Utf-8");
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        //得到session
        HttpSession session = req.getSession();
        //给session存东西
        session.setAttribute("name", new Person("李四", 18));
        //获取session 的id
        String id = session.getId();

        //判断session是不是新的
        if (session.isNew()) {
            resp.getWriter().write("session创建成功,Id:" + id);

        } else {
            resp.getWriter().write("session已经存在在服务器中了" +
                    ",id:" + id);
        }

       /* //session创建 时做了什么事情
        Cookie cookie = new Cookie("JSESSIONID", id);
        resp.addCookie(cookie);*/
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

得到Session
//得到session
        HttpSession session = req.getSession();
        Person person = (Person) session.getAttribute("name");

        System.out.println(person.toString());
注销
//手动注销
        session.invalidate();

   <session-config>
        <!--15分钟后session自动失效,以分钟为单位-->
        <session-timeout>15</session-timeout>
    </session-config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值