Servlet

全文来自于https://itbaima.net/document和 韩顺平的笔记

新版tomcat

1. 配置

请添加图片描述请添加图片描述

tomcat的服务器响应流程

请添加图片描述

Servlet的生命周期,Servlet是个接口

  1. Servlet的实现
public class TestServlet implements Servlet {
    public TestServlet(){
        System.out.println("我是构造方法!");
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("我是init");
    }
    @Override
    public ServletConfig getServletConfig() {
        System.out.println("我是getServletConfig");
        return null;
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("我是service");
    }
    @Override
    public String getServletInfo() {
        System.out.println("我是getServletInfo");
        return null;
    }
    @Override
    public void destroy() {
        System.out.println("我是destroy");
    }
}
  1. 生命周期的流程

只有调用这个servlet 生命周期才开始

也就是说只有访问了servlet映射的url 这个servlet才会开始init方法

  • 首先执行构造方法完成 Servlet 初始化
  • Servlet 初始化后调用 init () 方法。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 销毁前调用 destroy() 方法。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

HttpServlet,这个是Servlet的抽象类

类似于servlet的化简版
它已经帮助我们提前实现了一些操作,这样就会给我们省去很多的时间。
我们只要关注request和response就行。

差不多长这样

public class TestS2 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("init S2");
        super.init();
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("<h1>恭喜你解锁了全新玩法</h1>");    }

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

通过注解配置Servlet

@WebServlet({"/test3","/lala.html","*.do"})
public class TestS3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");  //设置响应内容类型
        resp.getWriter().write("lalala");
    }
}

tomcat 整合 mybatis

  1. servlet写法
@WebServlet("/reg")
public class TestS5 extends HttpServlet {
    private SqlSessionFactory sqlSessionFactory;
    @Override
    public void init() throws ServletException {
        URL resource = this.getClass().getClassLoader().getResource("mybatis-config.xml");
        String path = resource.getPath();
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(new FileInputStream(path));
            System.out.println("sqlSessionFactory = " + sqlSessionFactory);

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        super.init();
    }

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

            resp.setContentType("text/html;charset=UTF-8");
            //获取POST请求携带的表单数据
            Map<String, String[]> map = req.getParameterMap();
            //判断表单是否完整
            map.forEach((k,v)->{
                System.out.println(k+" "+ Arrays.toString(v));
            });
            var username = req.getParameter("username");
            var password = req.getParameter("password");
            var email = req.getParameter("email");
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.add(new User().setUsername(username).setPassword(password).setEmail(email));

        resp.getWriter().write("注册成功!");

    }
}
  1. mybatis配置
public interface UserMapper {
    @Insert("insert into users(username,password,email) values(#{user.username},#{user.password},#{user.email})")
    void add( @Param("user") User user);

    @Select("select * from users where username=#{username} and password=#{password}")
    User selectUserByNameAndPwd(@Param("username") String username, @Param("password") String password);
}

文件下载

  1. 后端
  • mavne引入commons-io
  • mybatis 的 Resources.getResourceAsStream()方法可以读取Resource下的文件
  • commons-io 的 IOUtils.copy()方法可以快速拷贝io
  • resp.setContentType(“image/jpeg”);告诉浏览器我要返回图片
@WebServlet("/file")
public class TestS6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        这两步已经告诉浏览器,我要返回图片 而且下面那个IOUtils.copy()方法会自动把图片写入resp的输出流
        resp.setContentType("image/jpeg");
        OutputStream outputStream = resp.getOutputStream();
//        Resources是mybatis提供的工具类,快速读取io
        URL resource = this.getClass().getClassLoader().getResource("5.jpg");
        String path = resource.getPath();
        System.out.println("path = " + path);
//        这个是直接读Resource下的文件 牛逼啊
        InputStream resourceAsStream = Resources.getResourceAsStream("5.jpg");
//        InputStream inputStream =new FileInputStream(path);
//        IOUtils是commons-io提供的,快速拷贝io
        IOUtils.copy(resourceAsStream, outputStream);

    }
}
  1. 前端
  • a标签的download属性可以指定下载的文件名
<a href="file" download="5.jpg">点我下载高清资源</a>

文件上传

  1. servlet
  • 需要加上@MultipartConfig注解
  • maven引入commons-io
  • maven引入commons-fileupload(这个我这里没用 但是确实是可以用)
@MultipartConfig //标记这个Servlet支持文件上传
@WebServlet("/file2")
public class TestS7 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//  他这个好像是没法拿名字 我要去找一下笔记
        try(FileOutputStream stream = new FileOutputStream("C:\\Users\\23584\\Desktop\\IDEAUtf-8\\new\\webT\\src\\main\\resources\\img3.png")){
            Part part = req.getPart("test-file");//前端的name属性
            IOUtils.copy(part.getInputStream(), stream);
            resp.setContentType("text/html;charset=UTF-8");
            resp.getWriter().write("文件上传成功!");
        }
    }
}
  1. 前端
  • form表单需要加上enctype="multipart/form-data"
  • input需要加上type="file"
  • input需要加上name="test-file",这个name属性是后端拿到文件的key
  • 如果想一次性上传多个文件,可以在input标签中加上multiple属性
<form action="file2" method="post" enctype="multipart/form-data">
    <input type="file" name="test-file">
    <input type="submit" value="上传">
</form>

初始化参数

当前servlet的初始化参数

@WebServlet(value = "/test9", initParams = {
        @WebInitParam(name = "name", value = "karl"),
})
public class TestS9 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(getInitParameter("name"));
        ServletContext context = getServletContext();
        System.out.println(context.getInitParameter("lbwnb"));
    }
}

全局初始化参数

直接在web.xml里和servlet同级别的位置加上

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

重定向和请求转发

重定向(Redirect)

用途:

  • 在完成POST请求后进行重定向,以防止表单的重复提交(POST/Redirect/GET模式)。
  • 在页面或资源被移动到新的URL时通知客户端。

请求转发(Forward)

用途:

  • 在不想暴露服务器内部结构的情况下,将请求委托给其他处理程序。
  • 当需要在多个组件之间共享请求数据时。

比较

特性重定向请求转发
跳转方式客户端跳转服务器端跳转
URL变化地址栏显示新的URL地址栏URL不变
HTTP状态码301, 302, 303, 307等通常是200 OK
数据传递数据不会自动传递到新的URL请求数据在转发中被保留并可用
请求/响应周期会启动新的请求/响应周期在同一个请求/响应周期内完成
可见性对客户端可见对客户端不可见
性能消耗更多资源,因为涉及到两次请求/响应相对节省资源,因为只有一次处理流程

举例来说,在Java的Servlet中,重定向和请求转发的实现如下:

重定向的Java Servlet实现:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // ... 其他处理逻辑 ...
    response.sendRedirect("http://www.example.com/newpage");
}

请求转发的Java Servlet实现:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // ... 其他处理逻辑 ...
    RequestDispatcher dispatcher = request.getRequestDispatcher("/newpage");
    dispatcher.forward(request, response);
}

Ajax(前后端以后直接用axios了)

  1. 前端
<body>
    <hr>
      <div id="time"></div>
    <br>
    <button onclick="updateTime()">更新数据</button>
</body>
<script>
    function updateTime() {
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                document.getElementById("time").innerText = xhr.responseText
            }
        };
        xhr.open('GET', 'time', true);
        xhr.send();
    }
</script>
  1. 后端
@WebServlet("/time")
public class TestS8 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String date = dateFormat.format(new Date());
        resp.setContentType("text/html;charset=UTF-8");

        resp.getWriter().write(date);
    }
}

ServletContext

请添加图片描述

ServletContext的简介

  1. ServletContext 接口:这是一个用于描述Servlet上下文的接口。Servlet上下文是一个为整个web应用提供信息的对象,它允许servlet之间共享数据。

  2. 唯一性:在一个web应用中,只存在一个 ServletContext 实例。这意味着在该应用中的所有Servlet都共享同一个 ServletContext,这有助于在不同的Servlet之间共享信息。

  3. 生命周期ServletContext 对象在web应用启动时被创建,在应用停止时销毁。这个生命周期与web应用的生命周期是一致的。

  4. 获取方式:可以通过 ServletConfig.getServletContext() 方法获取 ServletContext 对象的引用,或者在Servlet中使用 this.getServletContext()。这提供了一种在Servlet内部访问应用级信息的方式。

  5. 数据共享:由于所有的Servlet共享同一个 ServletContext,因此它可以用来在不同的Servlet之间共享数据。这使得 ServletContext 成为一个在整个应用范围内共享信息的有用工具。

  6. 获取web.xml中的配置:可以通过 ServletContext 获取在 web.xml 文件中配置的上下文参数(context-param)。这些参数通常包含了整个web应用的配置信息,而不是特定于某个Servlet的。

  7. 获取工程路径ServletContext 提供了方法来获取当前web应用的上下文路径,这通常是web应用的根路径。

  8. 获取绝对路径:还可以用它来获取web应用在服务器硬盘上的绝对路径。这在处理文件上传、下载等需要访问服务器文件系统的操作时非常有用。

  9. 存取数据ServletContext 像一个Map一样,可以用来存储和检索数据。由于它是由整个应用共享的,因此可以用来在不同的Servlet之间共享数据。

代码举例

第一部分:设置数据到 ServletContext
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class SetContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取ServletContext对象
        ServletContext context = this.getServletContext();

        // 设置属性
        context.setAttribute("data", "这是在ServletContext中设置的数据");

        // 响应输出
        response.getWriter().println("数据已设置到ServletContext");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
第二部分:从 ServletContext 读取数据
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class GetContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取ServletContext对象
        ServletContext context = this.getServletContext();

        // 从ServletContext获取数据
        String data = (String) context.getAttribute("data");

        // 响应输出
        response.getWriter().println("从ServletContext获取的数据是: " + data);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值