Servlet

Servlet获取参数

这里用一个小的表单网页举例
html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>add</title>
</head>
<body>
<form action="add" method="post">
  名称:<input type="text" name="name"><br/>
  价格:<input type="text" name="price"><br/>
  库存:<input type="text" name="count"><br/>
  备注:<input type="text" name="remark"><br/>
  <input type="submit" value="添加">
</form>
</body>
</html>

流程:

1.用户发送请求,action=add
2.项目中,web.xml中找到url-pattern = /add
3.web.xml找第十一行servlet-name = AddServlet
4.web.xml中找和servlet-mapping中servlet-name一致的servlet
5.web.xml找第八行的servlet-class ->AddServlet
6.用户发送的是post请求(method = post),因此tomcat会执行AddServlet中的doPost方法

Java代码:

注意:需要导入HttpServlet类,该类通过如下方法导入
在这里插入图片描述
通过找到对应项目,通过+号 Library 导入tomcat导入对应包

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

/**
 * @author ZHR
 * @version 1.0
 **/
public class AddServlet extends HttpServlet {
    @Override
    //响应网页中的post请求
    //HttpServletRequest req 将客户端的请求封装成Request
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取参数
        //req.getParameter()根据网页中标签的name获取对应的value值
        String name = req.getParameter("name");
        String price = req.getParameter("price");
        String count = req.getParameter("count");
        String remark = req.getParameter("remark");

        System.out.println(name);
        System.out.println(price);
        System.out.println(count);
        System.out.println(remark);
    }
}

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <servlet>
        <servlet-name>AddServlet</servlet-name>
        <servlet-class>AddServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>AddServlet</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>
</web-app>

<!--
1.用户发送请求,action=add
2.项目中,web.xml中找到url-pattern = /add
3.找第十一行servlet-name = AddServlet
4.找和servlet-mapping中servlet-name一致的servlet
5.找第八行的servlet-class ->AddServlet
6.用户发送的是post请求(method = post),因此tomcat会执行AddServlet中的doPost方法
-->

输出结果:
在这里插入图片描述
在这里插入图片描述
常见问题:
在这里插入图片描述

设置编码

在这里插入图片描述
加入编码格式后的Java代码:

import com.sun.net.httpserver.HttpsServer;

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

/**
 * @author ZHR
 * @version 1.0
 **/
public class AddServlet extends HttpServlet {
    @Override
    //响应网页中的post请求
    //HttpServletRequest req 将客户端的请求封装成Request
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //get方式目前不需要设置编码(基于tomcat8)

        //post方式下,设置编码,防止中文乱码
        //需要注意的是,设置编码的这一句代码需要在所有获取参数代码之前
        req.setCharacterEncoding("UTF-8");


        //获取参数
        //req.getParameter()根据网页中标签的name获取对应的value值
        String name = req.getParameter("name");
        String price = req.getParameter("price");
        String count = req.getParameter("count");
        String remark = req.getParameter("remark");

        System.out.println(name);
        System.out.println(price);
        System.out.println(count);
        System.out.println(remark);
    }
}

继承关系以及service方法

在这里插入图片描述

生命周期

在这里插入图片描述
2.默认情况下,第一次请求时,tomcat才会实例化,初始化。
优点:提高系统的启动速度
缺点:第一次请求时,耗时较长

因此需要设置Servlet的初始化时机
在这里插入图片描述
在web.xml中
在这里插入图片描述
3.Servlet容器是单例的,线程不安全

单例:所有的请求都是同一个实例去响应

线程不安全:一个线程需要根据这个实例中的某个成员变量值去做逻辑判断,但是在中间的某个时机,另一个线程改变了这个成员变量的值,从而导致第一个线程路径发生变化

解决方案:
1.尽量不要在Servlet中定义成员变量
2.如果需要成员变量,不要修改成员变量的值或者不要用成员变量进行逻辑判断

HTTP协议

在这里插入图片描述

Session

一.为什么要引入会话跟踪技术

http 是无状态的
在这里插入图片描述
例如:第一次请求是加入购物车,第二次请求是结账。
如果服务器不能区分是否是同一用户的,则会发生混乱。

二.会话跟踪技术

1.简单图示:
在这里插入图片描述
2.基本原理:
-
即服务器根据客户端的 sessionId 来区分不同的客户端

3.常用API
在这里插入图片描述
代码演示:

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 ZHR
 * @version 1.0
 **/
public class demo01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session , 如果获取不到,则创建新的
        HttpSession session = req.getSession();
        System.out.println(session.getId());

        //判断当前session是否是新的
        System.out.println(session.isNew());

        //获取session的非激活间隔时长,默认为1800s
        System.out.println(session.getMaxInactiveInterval());

        //设置session的非激活间隔时长
        session.setMaxInactiveInterval(60);
        System.out.println(session.getMaxInactiveInterval());

        //获取对话创建时间
        System.out.println(session.getCreationTime());

        //获取对话上一次进入的时间
        System.out.println(session.getLastAccessedTime());

       
    }
}

三.session保存作用域
在这里插入图片描述
在这里插入图片描述

服务器端转发和客户端重定向

1.介绍和方法
在这里插入图片描述
2.示意图

(1) 服务器端转发
在这里插入图片描述
(2) 客户端重定向
在这里插入图片描述

Thymeleaf - 视图模板技术

一.配置步骤:

1) 添加thymeleaf的jar包

1.新建一个lib文件夹,将jar包都复制粘贴到该文件夹中
在这里插入图片描述
2.点击右键,点击Add as Library
在这里插入图片描述
3.点击OK
在这里插入图片描述
4.打开Project Structure,找到Modules,点击加号,点击Library,找到lib,完成添加
在这里插入图片描述
在这里插入图片描述
5.在Problems中找到Fix,点击 Add “lib” to the artifact
在这里插入图片描述

2) 新建一个Servlet类ViewBaseServlet

在src中添加ViewBaseServlet

该类代码如下:


import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

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;

public class ViewBaseServlet extends HttpServlet {

    private TemplateEngine templateEngine;

    @Override
    public void init() throws ServletException {

        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();

        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);

        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);

        // ②设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");

        templateResolver.setPrefix(viewPrefix);

        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");

        templateResolver.setSuffix(viewSuffix);

        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);

        // ⑤设置是否缓存
        templateResolver.setCacheable(true);

        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");

        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();

        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);

    }

    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");

        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req, resp, getServletContext());

        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}

3) 在web.xml文件中添加配置
- 配置前缀 view-prefix
- 配置后缀 view-suffix

配置文件代码如下:

<!-- 配置上下文参数 -->
    <context-param>
        <param-name>view-prefix</param-name>
        <param-value>/</param-value>
    </context-param>
    <context-param>
        <param-name>view-suffix</param-name>
        <param-value>.html</param-value>
    </context-param>

根据逻辑视图名称 得到 物理视图名称
此处的视图名称是 index
那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图 名称上去
逻辑视图名称 : index
物理视图名称 : view-prefix + 逻辑视图名称 + view-suffix
所以真实的视图名称是: / index .html

4) 使得我们的Servlet继承ViewBaseServlet
在这里插入图片描述

二.简单实例
通过自定义的List集合,将数据导入到表格中

使用thymeleaf的标签
th:if , th:unless , th:each , th:text

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ZHR
 * @version 1.0
 **/
//Servlet从3.0版本开始支持注解方式的注册
@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Fruit> list = new ArrayList<>(4);
        for(int i = 0; i<4 ;i++){
            Fruit fruit = new Fruit("苹果",10,10,100);
            list.add(fruit);
        }
        //保存到作用域
        HttpSession session = req.getSession();
        session.setAttribute("list",list);


        //此处视图是index
        //那么thymeleaf会将这个 逻辑视图名称 对应到物理视图名称上去
        //逻辑视图 index
        //物理视图 view-prefix + 逻辑视图名称 + view-suffix
        //所以真是视图是 /index.html
        super.processTemplate("index",req,resp);
    }
}

注意:

1.//Servlet从3.0版本开始支持注解方式的注册
@WebServlet("/index")

2.通过下列代码来处理模板

super.processTemplate("index",req,resp);

html代码

<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="test.css">
</head>
<body>
<div id="container">
  <table id="table_fruit">
    <tr >
      <th >名称</th>
      <th >单价</th>
      <th>数量</th>
      <th>操作</th>
    </tr>
    <tr th:if="${#lists.isEmpty(session.list)}">
      <td colspan="4">库存为空</td>
    </tr>
<!--  if是判断是否为条件真 unless是判断是否为条件假 each是叠代,从session.list中依次取出一个对象赋给fruit  -->
    <tr th:unless="${#lists.isEmpty(session.list)}" th:each="fruit : ${session.list}">
      <td th:text="${fruit.getName()}">苹果</td>
      <td th:text="${fruit.getNum()}">5</td>
      <td th:text="${fruit.getPrice()}">20</td>
      <td><img src="1.jpg" height="24px" /></td>
    </tr>

  </table>
</div>
</body>
</html>

css代码

body{
    margin: 0;
    padding: 0;
}
div{
    position: relative;
    float: left;
}
#container{
    width: 80%;
    height: 100%;
    border: 1px solid blue;
    margin-left: 10%;

}
#table_fruit , #table_fruit th , #table_fruit tr , #table_fruit td {
    border: 1px solid gray;
    /* 边框合并 */
    border-collapse: collapse;
    /*  居中  */
    text-align: center;
    line-height: 28px;
}
#table_fruit{
    width: 60%;
    margin-top: 120px;
    margin-left: 20%;
}
#table1{
    /* 边框合并 */
    border-collapse: collapse;
    /*  居中  */
    text-align: center;
    line-height: 28px;
    width: 40%;
    margin-left: 30%;
}
.btn{
    width: 90px;
    height: 24px;
}

保存作用域

原始情况下,保存作用域我们可以认为有四个:
page(页面级别,现在几乎不用), request(一次请求响应范围) , session(一次会话范围) , application(整个应用程序范围)

1) request:一次请求响应范围
请添加图片描述
即通过客户端重定向不能访问(两次请求),而通过服务端转发可以访问(一次请求)

2) session:一次会话范围有效
请添加图片描述
只要是同一次对话,均可获得

通过下列代码获取Session

HttpSession session = req.getSession();

3) application: 一次应用程序范围有效
请添加图片描述
通过下列代码获取application

ServletContext application = req.getServletContext();

路径问题

请添加图片描述
注意绝对路径和base标签的用法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值