JavaWeb-Servlet(1)

Web-Servlet(1)

获取参数

大致流程

  1. 在WEB-INF同级下新建一个html文件,写一个表单
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>

</head>
<body>
    <form action="add" method="post">
        名称<input type="text" name="fname"/><br>
        价格<input type="text" name="price"/><br>
        库存<input type="text" name="fcount"/><br>
        备注<input type="text" name="remake"/><br>
        <input type="submit" value="添加"/><br>
    </form>

</body>
</html>
  1. 在src下新建一个类(AddSevlet)

注:要导入一个包:servlet-api,jar或是点击项目结构

找到自己建额项目

再这样

找到红线画的

//这里要添一点包哦
public class AddServlet extends HttpServlst{
    @Override
    public void doPost(HttpServletRequest request,HttpServletResponse response)throws IOExcepton,ServletExcption{
        String fname = request.getParameter("fname");
        String priceSrc = request.getParameter("price");
        Integer price = Integer.parseInt(priceSrc);            //强转一下
        String fcountSrc = request.getParameter("fcount");
        Integer fcount = Integer.parseInt(fcountSrc);
        String remake = request.getParameter("remake");

        System.out.println("fanme="+fname);
        System.out.println("price="+price);
        System.out.println("fcount="+fcount);
        System.out.println("remake="+remake);
    }
}
  1. 再在WEB-INF下新建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">
    <servlet>
        <servlet-name>AddServlet</servlet-name>
        <servlet-class>com.servlet.AddServlet</servlet-class>    <!--要写全哦-->
    </servlet>
    
    <servlet-mapping>
        <servlet-name>AddServlet</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>
</web-app>

基本流程/步骤

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

然后执行,如果看了上一篇的视频,并跟的做了的话可能会出现,404

没有关系将之前的Demo01改成自己html文件的名字就可以啦

再点击添加后,就可以再控制台看到这个了

Servlet的小基础

设置编码问题

  • 案例:

在上个项目中的水果表单添加中文时会出现乱码

  • 解决方法

在AddServlet中添加(tomcat8之后)

 request.setCharacterEncoding("UTF-8");

注:这句代码要在获取参数之前来填写

解决啦

Servlet的继承关系

继承关系(重点查看服务方法)

java.servlet.Servlet接口   
    java.servlet.GenericServlet抽象类   
        java.servlet.http.HttpServlet抽象子类  

相关方法

  • java.servlet.Servlet接口

void init(config) --初始化方法

void service(request,response) --服务方法

void destory() -- 销毁方法

  • java.servlet.GenericServlet抽象类

void service(request,response) -- 仍然是抽象的

  • java.servlet.http.HttpServlet抽象子类

void service(request,response) --不是抽象的

1.String method = req.getMethood() -- 获取请求的方式

2.各种if判断,根据请求方式的不同,决定去调用不同的do方法

3.在HttpServlet这个抽象类中,do方法都差不多

小结

  1. 继承关系:HttpServlet->GrnericsServlet->Servlet
  2. Servlet中的核心方法:init(),service(),destory()
  3. 服务方法:当有请求过来时,service方法会自动响应(其实时tomcat容器调用的)
  4. 在HttpServlet中我们会分析请求的方式,是get,post,head...然后决定调用那个方法(默认405实现风格--要我们子类去实现对应的方法,否则报405错误)
  5. 新建Servlet时,我们要考虑请求方法,从而决定重写哪个do方法

Servlet的生命周期

  • 生命周期的概念:从出生到死亡的过程,对应Servlet中3个方法init(),service(),destory()

来个小例子

  • html中
//演示Servlet的生命周期
public class Servlet02 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("正在初始化...");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("正在服务...");
    }

    @Override
    public void destroy() {
        System.out.println("正在销毁");
    }
}
  • web.xml中
 <servlet>
        <servlet-name>Servlet02</servlet-name>
        <servlet-class>src.com.servlets.Servlet02</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Servlet02</servlet-name>
        <url-pattern>/Demo02</url-pattern>
    </servlet-mapping>

看看效果:

  • 默认情况下:

       - 第一次接收请求时,这个Servlet会进行实例化(调用构造方法),初始化(调用init()),然后服务(调用service()) *提高 服务器的启动速度,第一次请求耗时较长*
    
       - 从第二次请求开始,每一次都是服务(点一下刷新,服务一次)
    
       - 当容器关闭时,其中的所有的Servlet实例化会被销毁,调用销毁方法
    
  • Servlet实例tomcat只会创建一个,所有的请求都是这个实例去响应

因此:如果要提高系统的启动速度,当前默认情况就是这样;如果需要提高响应速度,我们应该设置Servlet的初始化时机

  • Servlet在容器中是,单例的,线程不安全的(共用一个实例)

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

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

    -尽量不要在Servlet中定义成员变量,如果要定义,不要去根据成员便改良的值去做逻辑判断 / 修改成员变量的值

Servlet的初始化时机

默认是第一次接收请求时,实例化,初始化

我们可以通过来设置servlet启动的先后顺序,数字越小,启动越靠前,min:0

修改之后

Http协议

介绍

  1. Http:Hyper Text transfer Protocol超文本传输协议。确定了请求和响应的数据格式

  2. Http是无状态的

  3. Http请求响应包含两个部分:请求和响应

    -请求:请求包含3个部分:1.请求行  2.请求(消息)头  3.请求体
    
    -响应:响应也含3个部分:1.响应行  2.响应(消息)头  3.响应体
    

请求

请求行

作用:展现当前请求的最基本信息

  • 请求方式
  • 访问地址
  • HTTP协议的版本

在我刚才的页面上可以查看(F12)

请求(消息)头

作用:通过具体的参数对本次请求进行详细说明(包含很多客户端需要告诉服务器的信息,eg:我的浏览器型号、版本...)

格式:键值对,键和值之间只用""隔开

请求体

作用:作为请求的主体,发送数据给服务器,具体来说其实就是POS请求方法下的请求参数

格式:

  • get方式,没有请求体,但是有一个queryString
  • post方式,有请求体,form data
  • josn格式,有请求体,request payload

响应

响应行
  • 协议
  • 响应状态码
  • 响应状态
响应(消息)头

包含服务器信息:服务器发送给浏览器的信息(内容的媒体类型、编码...)

响应体

响应的实际内容(eg:请求html的内容)

会话

解释Http无状态:服务器无法判断两次(或多次)请求是否是同一个客户端发来的

-实际问题:第一次请求时添加商品到购物车,第二次时结账,若无法区分是否时同一用户发的请求,会导致混乱

-通过会话跟踪技术来解决

会话跟踪技术

  • 客户端第一次发请求给服务器,服务器获取session,获取不到,则创建一个新的,然后响应给客户端
  • 下次客户端给服务器发请求时,会把sessionID带给服务器,那么服务器就能获取到了,服务器就判断这一次和某次请求时同分异构客户端发出的,来区分客户端
  • 常用的API
request.getSessin() -> 获取当前的会话,没有创一个新的
request.getSession(true) -> 同上
request.getSession(false) -> 获取当前会话,没有则返回null,不会创建新的
    
session.getId() -> 获取sessionID
session。isNew -> 判断当前session是否是新的
session.getMaxInactiveIntervsl() -> session的非激活间隔时长(默认1800s)
session.setMaxInactiveIntervsl()
    
session.invalidata() -> 强制让会话立即失效
session.get
    

小例子(web.xml就不写了,都一样)

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session,如果获取不到,则创键一个新的
        HttpSession session = req.getSession();
        System.out.println("sessionID:"+session.getId());
    }

session保存作用域

1.session保存作用域是和具体的某一个session对应的

2.常用的API

//可以有多个key,但不要重复,一旦重复,会覆盖之前的value
void session.setAttribute(k,v);
Object session.getAttribute(k);
void removeAttribute(k);

大家如果不想实验代码就先跳过下面这一段

两个不同的类哦

//session保存作用域:存储
public class Servlet04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().setAttribute("uname","lina");
    }
//session保存作用域:获取(它是Demo05)
public class Servlet05 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object unameObj = request.getSession().getAttribute("uname");
        System.out.println("unameObj:"+unameObj);
    }

同上web.xml就不写了

最后会在控制台输出 lina(可以尝试换一个浏览器搜索Demo05,结果是null哦)

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

  • 服务器内部转发:req.getRequestDispatcher("...").forward(req,resp);

-是一次请求响应的过程,对于客户端,内部经历了多少次转发,客户端时不知道的

-地址栏没有变化

例子:(注意看红色的线)

  • 客户端重定向:resp.sendRedirect("...");

-两次请求响应的过程,客户端知道URL有变化

-地址栏有变化

例子:

posted @ 2022-04-04 09:03  T,a,o  阅读(89)  评论(0编辑  收藏  举报