Servlet初识

一、Servlet是什么

在这里插入图片描述

(1)Servlet:Server Applet,全称java servlet。java编写的服务端程序,交互式的浏览和修改数据,生成动态web内容。狭义的Servlet是java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。一般人们理解为后者。
(2)Servlet运行在支持java的应用服务器中。Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的web服务器。
(3)Servlet的工作模式:

  • 客户端发送请求至服务器
  • 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器
  • 服务器将响应返给客户端

二、Servlet API

在这里插入图片描述

三、第一个Servlet

3.1、创建一个类实现接口Servlet

package com.jsonliu.test;

import javax.servlet.*;
import java.io.IOException;

/**
 * @Author: JSONLiu
 * @Description:
 * @Date Created in 2021-08-14 17:42
 * @Modified By:
 */
public class LoginServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //初始化方法
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)
            throws ServletException, IOException {
        //处理post、get的方法
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        //销毁方法
    }
}

3.2、在web.xml中配置映射关系

<servlet>
    <servlet-name>自定义名称</servlet-name>
    <servlet-class>处理请求的类的完整路径</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>自定义名称</servlet-name>
    <url-pattern>请求名</url-pattern>
</servlet-mapping>

标签执行顺序:
请求-> web.xml -> servlet-mapping标签中的url-pattern标签内容和请求进行匹配 -> 匹配成功后找到servlet-mapping中servlet-name -> 去servlet中找和上一个servlet-name相同的name值 -> 去找servlet中servlet-class中处理类的完整路径

四、Servlet工作原理

(1)Servlet接口定义了Servlet和servlet容器之间的契约。这个契约是:Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它具体的方法。在一个应用程序中,每种Servlet类型都只有一个实例。
(2)用户请求致使Servlet调用Service()方法,并传入一个ServletResquest对象和一个ServletResponse对象,这两个对象都是有Servlet容器(例:Tomcat)封装好的,不需要程序员去实现,可以直接使用。
(3)ServletResquest中封装了当前http请求,开发人员不需要解析和操作原始的http数据。ServletResponse表示当前用户的http响应,程序员只需要操作ServletResponse就可以把响应发回给用户。
(4)对于每一个应用程序,Servlet容器还会创建一个ServletContext对象。这个对象封装了应用程序上下文的环境详情。每个应用程序只有一个ServletContext。每个Servlet对象也有一个封装Servlet配置的ServletConfig对象。

五、Servlet的生命周期

当客户端发送首次请求时,由容器(web服务器tomcat)去解析请求,根据请求找到对应的Servlet,判断该类的对象是否存在,不存在则创建对象实例,调取init()方法初始化操作。初始化完成后调取service()方法,由service()判断客户端请求方式,如果是get执行doGet(),如果是post执行doPost()。处理方法完成后,作出相应的回应给客户端,单次请求结束。
当用户第二次发送请求时候,会判断对象是否存在,但不会执行init()方法。而直接执行service()方法调取doGet()或者doPost()。
四个过程:

  • 实例化 – 创建servlet实例
  • 初始化 – init()
  • 处理请求 – service()
  • 服务终止 – destory()
    在这里插入图片描述

六、请求

HttpServletResquest是Http环境中的Servlet请求。它扩展与java.servlet.ServletResquest接口。
常用方法:
String getParameter(String name)根据表单组件名称获取提交数据,返回值是String。(注意:服务器在接收数据时使用字符串统一接收)
String getParameterValues(String name)获取表单组件对应多个值时的请求数据
void setCharacterEncoding(String charset)指定每个请求的编码(针对post请求才起作用)
ResquestDispatcher getResquestDispatcher(String path) 跳转页面(返回一个ResquestDispatcher对象,该对象的foward()方法用于转发请求)
request.getResquestDispatcher("…/success.jsp").foward(request,response);

// 存值
request.setAttribute("key",value);

// 取值
request.getAttribute("key");
// 取值后向下转型
String uname=(String)request.getAttribute("key");

6.1、客户端发送数据给服务器

方式1:Get/Post提交表单
方式2:通过a标签发送数据(get提交)

<a href="请求名?key=value&key=value&key=value">

这里的key等于表单元素的控件名,value等于表单中控件的value属性。
数据获取方式:

String name=request.getParameter("name");

方式3:地址栏直接拼接get请求
方式4:JS提交Get请求

location.href="目标请求?key=value&key=value"

6.2、处理请求乱码

方式1:
//post提交管用

setCharacterEncoding("UTF-8");

方式2:
//get提交时中文乱码

String s=new String(变量名.getBytes("ISO-8859-1"),"UTF-8");

方式3:
修改tomcat服务器server.xml中字符集
在这里插入图片描述

6.3、get和post的区别

  1. get请求,所有请求数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL编码采用ASCII码,所有的非ASCII码需要编码后再传输。
  2. post请求,会把所有的数据放到Http请求包的包体中。get请求的数据会暴露在地址栏中,post则不会。
  3. 传输数据的大小:get请求时,特定浏览器和服务器会对URL有长度限制,get请求时传输数据会收到URL长度限制。post理论上不受限制,但是实际开发中Apache、IIS等服务器对post提交数据大小进行设置。
  4. Post安全性比get高

七、响应

// HttpServletResponse接口继承ServletResponse接口,专门用来封装Http响应消息。在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法。
// 常用方法:
void addCookie(Cookie var1); //给这个响应添加一个cookie
void sendRedirect(String var1);//发送一条响应码,将浏览器跳转至指定位置
PrintWriter getWriter();//获得字符流,通过字符流的write(String s)方法可以将字符串
// 设置到response的缓冲区,随后tomcat将response缓冲区中的内容组装成Http响应返回给浏览器端。
setContentType();//设置响应内容的类型

7.1、重定向和转发对比

重定向:

request.setRedirect();

转发:

request.getDispatcher("../success.jsp").foward(request,response);

都是用来跳转页面。
不同点:

  • 重定向时会改变地址栏地址信息,request中存储的数据会丢失;转发时,地址栏中显示的是请求页面地址,request中存储的数据能保留。

  • 转发属于一次请求一次响应,重定向属于两次请求两次响应。

  • 使用out对象向浏览器中输出js或者html、css

out.print("<script type='text/javascript'>
alert('登录失败');location.href='../login.jsp'</script>");

注:使用js跳转页面,也会丢失request中的数据。

八、会话

request中存的值只能在单次请求中保存,保存的数据不能跨页面,当重定向时,request保存的值会丢失。session中的数据可以在多个页面间共享,即使重定向,数据也不会丢失。
会话的概念:从打开浏览器到关闭浏览器,期间访问浏览器,就称为一次会话。
常用方法:

void setAttribute(String key,Object val);//以key/value形式保存对象值,将数据存储在服务器端
Object getAttribute(String key); //通过key获取对象值
void invalidate();//设置session对象失效
String getId();//获取sessionid,当第一次登陆成功后,session会产生一个唯一ID,
// 浏览器之后访问如果发现ID还是之前那个ID,那么说明当前访问属于同一个会话。
void setMaxInactiveinterval(int interval);//设置session的非活动时间

示例:
方式1:session.setMaxInactiveinterval(10*60); //设置有效时间为10分钟
方式2:修改web.xml

<session-config>
    <session-timeout>10</session-timeout> //单位:分钟
</session-config>

int getMaxInactiveinterval();//获取session的有效非活动时间,默认30分钟
void removeAttribute(String key);//从session中删除指定key对象

session失效的三种办法:
1、invalidate
2、removeAttribute(“key”);
3、直接关闭浏览器

九、获得初始化参数

request.setCharacterEncoding(“UTF-8”);//代码耦合度太高,不便于后期维护,可以通过初始化参数修改。
实现方式:
1、web.xml中先定义初始化参数

<servlet>
    <servlet-name></servlet-name>
    <servlet-class></servlet-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</servlet>

2、servlet中获取初始化参数,重写init()方法

public void init(ServletConfig config) throws ServletException{
    encoding=config.getInitParamter("encoding");
}

注意:这种初始化参数仅限于当前servlet使用。
9.2、全局初始化参数
1、定义context-param,与servlet同级别:

<context-param>
    <param-name>encoding</param-name>
    <param-value>utf-8</param-value>
</context-param>

2、获得数据

@Override
public void init(ServletConfig config)throws ServletException{
    String encoding=config.getServletContext().getInitParameter("encoding");
}

十、Servlet3.0

@WebServlet注解配置Servlet
从Servlet3.0开始,配置Servlet支持注解方式,同时也保留了web.xml方式。所以使用Servlet有两种方式:
Servlet类使用@WebServlet进行配置
web.xml中进行配置
属性 类型 是否必须 说明asyncSupported boolean 否 指定Servlet是否支持异步操作displayName String 否 指定Servlet显示名称initParams webInitParam[] 否 配置初始化参数loadOnStartup int 否 标记容器是否在应用启动时就加载这个Servletname String 否 指定Servlet名称urlPatterns/value String[] 否 两个属性相同,指定Servlet处理的URL

<servlet>
    <servlet-name>a</servlet-name>
    <servlet-class>
    <!--处理类的完整路径-->
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

10.1、代码示例
UserServlet,注解中配置,web.xml中不需要配置

package com.jsonliu.test;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
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.Enumeration;

/**
 * @Author: JSONLiu
 * @Description:
 * @Date Created in 2021-08-15 13:55
 * @Modified By:
 */
@WebServlet(
        name = "myUserServlet",
        urlPatterns = "/user/test",
        loadOnStartup = 1,
        initParams = {
                @WebInitParam(name="name",value="小明"),
                @WebInitParam(name="pwd",value="123456")
        }
)
public class UserServlet extends HttpServlet {
    private static final long serialVersionUID=7109220574468622594L;
    @Override
    public void init(ServletConfig config)throws ServletException{
        super.init(config);
        System.out.println("servlet初始化...");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer=resp.getWriter();
        writer.append("hello servlet!<br/>");
        writer.append("servletName:"+getServletName()+"<br/>");
        ServletConfig config=this.getServletConfig();
        Enumeration<String> parameterNames = config.getInitParameterNames();
        while (parameterNames.hasMoreElements()){
            String paramName = parameterNames.nextElement();
            writer.append(paramName+":"+config.getInitParameter(paramName)+"<br/>");
        }
        writer.close();
    }

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

效果
在这里插入图片描述

说明:

  1. loadOnStartup:标记容器是否在启动时就加载Servlet,默认为不配置或为负数时,表示客户端第一次请求Servlet时才加载,0或者正数表示启动应用就加载。数值越小,加载该Servlet优先级越高。
  2. name:可以指定,也可以不指定。通过getServletName()获取,若不指定,为完整类名。
  3. urlPatterns/value:String[],可以配置多个映射,如:urlPatterns={"/user/test","/user/example"}
  4. urlPatterns常用拦截规则:
    /*或者/:拦截所有
    .do:拦截指定后缀
    /user/test:拦截路径
    /user/.do、/.do、test
    .do:都是非法的,启动时会报错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑谈子云亭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值