JavaWeb - Servlet 的一些使用

目录

Servlet 基础

写一个Servlet

Servlet是如何运行的?

Servlet流程图

Servlet生命周期(三个阶段)

HttpServletRequest与HttpServletResponse 

Servlet中文问题

转发与重定向

Servlet 高级用法

Cookie与Session

ServletContext与ServletConfig

Servlet三大作用域:request、session、servletContext

过滤器与监听器


Servlet是一个在Web服务器(l例如:Tomcat容器)中运行的小型Java程序。

Servlet通常通过HTTP(超文本传输​​协议)接收和响应来自Web客户端的请求。

<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
	<version>4.0.0</version>
</dependency>

Servlet 基础

写一个Servlet

继承关系:abstract class HttpServlet extends GenericServlet
继承关系:abstract class GenericServlet implements Servlet, ServletConfig, Serializable

step1. 写一个java类,实现Servlet接口或者继承HttpServlet抽象类。
step2. 编译。
step3. 打包。
    即创建一个具有如下结构的文件夹:
    appname (可自定义 一般为webapp) 
        WEB-INF
            classes (放.class文件)
            lib (放.jar文件  可选)
            web.xml (部署描述文件)
step4. 部署。
    将step3创建好的整个文件夹拷贝到相应的Serlvet容器里面。
    注:
        将step3创建好的整个文件夹使用jar命令压缩成".war"结尾的文件,然后再拷贝。
step5. 启动Servlet容器,访问Servlet。
    http://ip:port/appname/url-pattern

代码如下:

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    // 一些 方法  init(),doGet(),doPost(),destroy() 方法 
}

启动容器,浏览器输入  http://localhost:8080/项目名/LoginServlet

ps: @WebServlet("/LoginServlet") servlet 3.0.0后支持了注解的形式,可以不用在web.xml配置如下内容

 

Servlet是如何运行的?

比如,在浏览器地址栏输入 http://localhost:8080/项目名/继承了HttpServlet的类名,发生了什么?

step1.浏览器依据ip和port建立连接。
step2.浏览器将请求相关的数据打包(即创建请求数据包)然后发送给servlet容器。
step3.servlet容器解析请求数据包,并且将解析到的数据存放到request对象里面,同时,还会创建一个response对象。
step4.servlet容器依据请求路径找到对应的servlet的配置,然后容器将servlet实例化。
step5.servlet容器调用servlet的service方法。
注:会将request和response作为参数传递进来,开发人员可以调用request对象的方法来获得请求数据包里的数据(比如获取请求参数值),
    也可以将处理结果写到response对象里面。
step6.容器从response对象中取出处理结果,然后创建响应数据包并发送给浏览器。
step7.浏览器解析响应数据包,生成相应的页面。

Servlet流程图

 

Servlet生命周期(三个阶段)

1、初始化阶段 调用 init() 方法

只执行一次   可以设置容器启动时 就加载  里面参数 1为优先级    
<servlet>
    <servlet-name>xxxxx</servlet-name>
    <servlet-class>yyyyyy</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

2、响应客户端请求阶段调用 service() 方法 

HttpServletRequest request    执行 (service底层还是) doGet,doPost 方法
HttpServletResponse response  响应  

3、终止阶段调用 destory() 方法

容器在删除Servlet实例之前,会调用该实例的destroy方法。
该方法只会调用一次。

 

HttpServletRequest与HttpServletResponse 

request 常用方法

request.getRequestURL(): 浏览器发出请求时的完整URL,包括协议 主机名 端口(如果有)" 
request.getRequestURI(): 浏览器发出请求的资源名部分,去掉了协议和主机名" 
request.getQueryString(): 请求行中的参数部分,只能显示以get方式发出的参数,post方式的看不到
request.getRemoteAddr(): 浏览器所处于的客户机的IP地址
request.getRemoteHost(): 浏览器所处于的客户机的主机名
request.getRemotePort(): 浏览器所处于的客户机使用的网络端口
request.getLocalAddr(): 服务器的IP地址
request.getLocalName(): 服务器的主机名
request.getMethod(): 得到客户机请求方式一般是GET或者POST

request 获取参数:

request.getParameter(): 是常见的方法,用于获取单值的参数
request.getParameterValues(): 用于获取具有多值的参数,比如注册时候提交的 "hobits",可以是多选的。
request.getParameterMap(): 用于遍历所有的参数,并返回Map类型。

request 服务端传参:

setAttribute(key,value)和getAttribute(key,value)可以用来在进行服务端跳转的时候,在不同的Servlet之间进行数据共享

response 设置响应内容:

PrintWriter pw= response.getWriter();
pw.println("Hello Servlet");

response 设置响应格式:

response.setContentType("text/html"); //html格式

response 设置响应编码:

1. response.setContentType("text/html; charset=UTF-8");
2. response.setCharacterEncoding("UTF-8");
这两种方式都需要在response.getWriter调用之前执行才能生效。
第一种方式:不仅会设置响应的内容的编码为UTF-8,而且还通知浏览器使用UTF-8编码方式进行显示
第二种方式:只会设置响应的内容的编码为UTF-8

response 设置不使用缓存:

// 通知浏览器不要使用缓存
response.setDateHeader("Expires",0 );
response.setHeader("Cache-Control","no-cache");
response.setHeader("pragma","no-cache");

 

Servlet中文问题

获取中文的参数

1、页面上使用UTF-8编码 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

2、get请求 前端路径使用 encodeURI(路径);

3、post请求 后端request.setCharacterEncoding("UTF-8") 并且在request.getParameter()之前 

返回中文的响应

response.setContentType("text/html; charset=UTF-8");

 

转发与重定向

转发 :request.getRequestDispatcher("url").forward(request, response);

重定向 :response.sendRedirect("url");

转发与重定向区别

区别转发重定向
调用的方法request的方法reponse的方法
请求服务器次数1次2次,所以 request 是不同的,如果request设置了值得话 会失效
url地址栏不改变改变
目标地址转发有限制(要求属于同一个web应用)没有任何限制

 

 

Servlet 高级用法

Cookie与Session

当浏览器访问服务器时,服务器将少量数据以set-cookie消息头的形式发送给浏览器,浏览器会将这些数据保存下来。 
当浏览器再次访问服务器时,浏览器会将之前保存的这些数据以cookie消息头的形式发送给服务器。

当浏览器访问服务器时,服务器会创建一个session对象(该对象有一个唯一的id,一般称之为sessionId),
接下来,服务器会将sessionId以cookie的方式发送给浏览器;
当浏览器再次访问服务器时,会将sessionId发送过来,服务器就可以利用sessionId找到对应的session对象。

添加Cookie

Cookie c = new Cookie(String name,String value);
response.addCookie(c);

读取Cookie

Cookie[] request.getCookies();
注: a. Cookie对象封装了cookie中的数据。
    b. 该方法有可能返回null。
String cookie.getName();
String cookie.getValue();

Cookie的编码问题

a.Cookie只能保存合法的ascii字符,对于中文,需要转换成对应的ascii字符的形式。
String URLEncoder.encode(String str,String charset);
String URLDecoder.decode(String str,String charset);
b.建议,在添加cookie时,都统一编码处理。

Cookie的生存时间

a.默认情况下,浏览器会将Cookie保存在内存里面,只要浏览器不关闭,Cookie就会一直存在。如果浏览器关闭,Cookie就会被删除。
b.可以调用setMaxAge方法来设置Cookie的生存时间。
    cookie.setMaxAge(int seconds);
    注:单位是秒 
       值>0 浏览器会将cookie保存在硬盘上,如果超过指定的时间,则浏览器会删除该cookie。
       值<0 默认值(浏览器会将cookie保存在内存里面)。
       值=0 删除cookie。
            比如要删除一个名称为username的cookie:
                Cookie c = new Cookie("username","");
                c.setMaxAge(0);
                response.addCookie(c);

Cookie的路径问题

a.什么是Cookie的路径问题?
浏览器再向服务器上的某个地址发请求时,会比较该地址是否符合Cookie的路径的要求,只有符合条件的Cookie才会被发送。

b.Cookie的默认路径
 等于添加该Cookie的web组件的路径,比如
/day06/biz01/addCookie1.jsp,则该jsp添加的cookie,默认路径是"/day06/biz01"。

c.匹配规则
 只有当请求地址等于cookie的路径或者是其子路径时,浏览器才会将该cookie发送给服务器。
比如,cookie的路径是"/day06/biz01",则:
/day06/findCookie1.jsp   no
/day06/biz01/findCookie2.jsp  yes
/day06/biz01/sub/findCookie3.jsp yes

d.可以调用setPath方法来设置cookie的路径。
    Cookie.setPath(String path);

如何获得session对象?

HttpSession s = request.getSession(boolean flag);
注: flag为true时:
    先查看请求当中是否有sessionId,如果没有,则创建一个符合HttpSession接口的session对象;
    如果有sessionId,则依据该sessionId查找对应的session对象,
    如果找到了,则返回该对象,如果找不到,则创建一个新的session对象。

    flag为false时:
    先查看请求当中是否有sessionId,如果没有,返回null;
    如果有sessionId,则依据该sessionId查找对应的session对象,
    如果找到了,则返回该对象,如果找不到,返回null。
request.getSession(true) 与 request.getSession()  等价

Session常用方法

String  session.getId();
session.setAttribute(String name,Object obj);
Object session.getAttribute(String name);
session.removeAttribute(String name);

session超时

服务器会将空闲时间过长的session对象删除掉,目的是为了节省内存空间。
默认的超时时间,大部分服务器默认是30分钟。
-------解决方案----------
 
1、如在tomcat-8.5.32\conf\web.xml中设置
Tomcat默认session超时时间为30分钟,可以根据需要修改,负数或0为不限制session失效时间
<session-config>
    <session-timeout>30</session-timeout>
</session-config>

2、在工程的web.xml中设置
<!-- 设置失效时间为10分钟 -->
<session-config>
      <session-timeout>10</session-timeout>
</session-config>

3、设置两次请求之间的最大间隔时间,如果超过这个间隔时间,session对象会被删除。
d.setMaxInactiveInterval(int seconds)

优先级是 3>2>1

删除session对象

session.invalidate();

session验证

step1.登录成功之后,在session对象上绑订相关数据。比如:

    session.setAttribute("user",user);

step2.当用户访问需要保护的资源(比如,访问用户列表),则进行session验证:

    Object obj = session.getAttribute("user");
    if(obj == null){
        //没有登录
        response.sendRedirect("login.jsp");
    }

Cookie与Session区别

区别CookieSession
存储位置浏览器服务器
内存大小少量数据,只能保存合法的ascii字符更多数据,且数据类型更丰富
安全性不安全安全

 

ServletContext与ServletConfig

ServletContext:每一个web应用都会创建一个符合ServletContext接口要求的对象

ServletConfig:表示的是某一个Servlet的配置文件

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        ServletConfig config = this.getServletConfig();
        // 解决响应中文乱码
        resp.setHeader("Content-Type","text/html;charset=UTF-8");
        resp.getWriter().print("context:"+context.getInitParameter("context"));
        resp.getWriter().print("config:"+config.getInitParameter("config"));
    }
}

web.xml 配置

<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.storm.shop.LoginServlet</servlet-class>

	<!-- 配置单一Serlvet区域 servletconfig的初始化参数 -->
    <init-param>
        <param-name>config</param-name>
        <param-value>我是config</param-value>
    </init-param>

</servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>

<!-- 配置全局 servletconext的初始化参数 -->
<context-param>
    <param-name>context</param-name>
    <param-value>我是context</param-value>
</context-param>

总结:servletContext/servletConfig作用域不同,一般都是应用于 过滤器,监听器,容器启动读取自己设置的配置文件、

 

Servlet三大作用域:request、session、servletContext

区别/使用requestsessionservletContext
作用域/生命周期在当前请求中有效在当前会话中有效在当前项目(服务器)中有效
使用场景跟当前操作功能相关跟用户信息相关跟项目全局信息相关

 

过滤器与监听器

过滤器

Servlet规范当中定义的一种特殊的组件,用来拦截Servlet容器的调用过程。
注:当请求到达容器之后,如果有过滤器的话,容器会先调用过滤器。

如何写过滤器

step1.写一个java类,实现Filter接口。
step2.在doFilter方法里面,编写相应的拦截处理逻辑。
step3.配置过滤器(web.xml)。

过滤器配置 web.xml

  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
<!-- 解决中文乱码 -->
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <!--不写 dispatcher标签 默认为 request -->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>

监听器

Servlet规范当中定义的一种特殊的组件,用于监听Servlet容器产生的事件并进行相应的的处理
注:容器器产生的事件主要有两大类:
    1、生命周期相关的事件,指的是容器创建了或者销毁了request、session、Servlet上下文(ServletContext)时产生的事件。
    2、绑订数据相关的事件,指的是调用了request、session、Servlet上下文的setAttribute和removeAttribute时产生的事件。

如何写一个监听器

step1.写一个java类,实现相应的的监听器接口。 
注:具体实现哪个接口,要看要监听的事件类型是什么
	对ServletContext的监听 需要实现 ServletContextListener接口 Servlet上下文初始化和销毁时的监听器。
	对ServletContext的监听 需要实现 ServletContextAttributeListener接口 Servlet上下文参数变化时的监听器
	
	对HttpSession的监听 需要实现 HttpSessionListener接口 HttpSession初始化和销毁时的监听器。
	对HttpSession的监听 需要实现 HttpSessionAttributeListener接口 HttpSession参数变化时的监听器。
	
	对ServletRequest的监听 需要实现 ServletRequestListener接口 ServletRequest初始化和销毁时的监听器。
	对ServletRequest的监听 需要实现 ServletRequestAttributeListener接口 ServletRequest参数变化时的监听器。

step2.在监听器接口方法当中,实现相应的的监听处理逻辑。
step3.配置监听器。(web.xml)

监听器配置 web.xml

step1. 
servlet3.1之后 支持注解 所以 只需要 在实现监听器的类 上面加上@WebListener
@WebListener
public class Storm implements ServletContextListener {
    // .....
}

step2. 
<!-- 配置日志 -->
  <listener>
    <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
  </listener>

Servlet加载顺序

servletContext>Listener>Filter>Servlet

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值