JavaWeb:Servlet与过滤器、EL与JSTL

初识Servlet

Servlet是一种服务器端的Java应用程序,只有当一个服务器端的程序使用了Servlet API的时候,这个服务端的程序才能称之为Servlet。

Servlet本身不做任何业务处理,只是接收请求并决定调用哪个JavaBean去处理请求,确定用哪个页面来显示处理返回的数据

Servlet的工作模式

  • 客户端发送请求至服务器

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

  • 服务器将响应返回客户端

JSP与Servlet之间的关系

Servlet API

1.实现Servlet接口

javax.servlet.Servlet接口:所有Java Servlet的基础接口类,规定了必须由Servlet具体类实现的方法集

2.继承GenericServlet类

javax.servlet.GenericServlet类:是Servlet的通用版本,是一种与协议无关的Servlet

3.继承HttpServlet类

javax.servlet.http.HttpServlet类:在GenericServlet基础上扩展的基于Http协议的Servlet

Servlet的使用

Servlet接口中定义的主要方法

  • init():Servlet的初始化方法,仅仅会执行一次

  • service():处理请求和生成响应

  • destroy():在服务器停止并且程序中的Servlet对象不再使用的时候调用,只执行一次

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;
 
    ServletConfig getServletConfig();
 
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
 
    String getServletInfo();
 
    void destroy();
}

init( )、service( )、destroy( )是Servlet生命周期的方法,代表了Servlet从出生到工作再到死亡的过程。

Servlet生命周期各个阶段

  1. 加载和实例化

  2. 初始化

  3. 处理请求

  4. 销毁

生命周期谁来做何时做
实例化Servlet 容器当Servlet容器启动或者容器检测到客户端请求时
初始化Servlet 容器实例化后,容器调用Servlet的init()初始化对象
处理请求Servlet 容器得到客户端请求并做出处理时
销毁Servlet 容器当程序中的Servlet对象不再使用的时候,或者Web服务器停止运行的时候

ServletRequest

  • 封装客户的请求信息

  • 作用相当于JSP内置对象request

public interface ServletRequest {
    int getContentLength();//返回请求主体的字节数
    String getContentType();//返回主体的MIME类型
    String getParameter(String var1);//返回请求参数的值
}

ServletResponse

  • 创建响应信息,将处理结果返回给客户端

  • 作用相当于JSP内置对象

responseServletConfig

  • 包含了Servlet的初始化参数信息

部署运行Servlet

配置Servlet:

配置<servlet>元素:把Servlet内部名映射到一个Servlet类名

<servlet>
        <servlet-name>UserLogin</servlet-name>
        <servlet-class>com.mhl.servlet.UserLoginServlet</servlet-class>
​
</servlet>

配置<servlet-mapping>元素:把用户访问的URL映射到Servlet的内部名

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

注意:<servlet-mapping>与<servlet>中的<servlet-name>必须一致

初始化参数设置:

配置<init-param>元素:修改字符编码为utf-8

<servlet>
    ……
    <init-param>
        <param-name>charSet</param-name>
        <param-value>utf-8</param-value>
    </init-param>  
</servlet>

使用继承HttpServlet创建servlet类:

public class UserLoginServlet extends HttpServlet {
    String charSetContent = null;
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("这是init");
        charSetContent = config.getInitParameter("charSetContent");
        super.init();
    }
​
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是service");
        super.service(req, resp);
    }
​
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是doGet");
        req.setCharacterEncoding(charSetContent);
        String name =req.getParameter("name");
        System.out.println("name==" + name);
        super.doGet(req, resp);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是doPost");
        super.doPost(req, resp);
    }
​
    @Override
    public void destroy() {
        super.destroy();
    }
}

过滤器

  • 过滤器是向Web应用程序的请求和响应添加功能的Web服务组件

  • 过滤器可以统一地集中处理请求和响应

  • 使用过滤器技术实现对请求数据的过滤

过滤器原理

使用过滤器时,过滤器会对游览器的请求进行过滤,过滤器可以动态的分为3个部分,1.放行之前的代码,2.放行,3.放行后的代码,这3个部分分别会发挥不同作用。

  • 第一部分代码会对游览器请求进行第一次过滤,然后继续执行

  • 第二部分代码就是将游览器请求放行,如果还有过滤器,那么就继续交给下一个过滤器

  • 第三部分代码就是对返回的Web资源再次进行过滤处理

过滤器的使用步骤

建立实现javax.servlet.Filter接口的类,实现过滤行为

doFilter(...)  {
//过滤请求
chain.doFilter(request, response); //调用下一个过滤器或Web资源
//过滤响应
}

在web.xml中配置过滤器

<filter>
    <filter-name>过滤器名</filter-name>
    <filter-class>过滤器的完全限定名</filter-class>
</filter>
<filter-mapping>
    <filter-name>过滤器名</filter-name>
    <url-pattern>过滤器映射的Web资源</url-pattern>
</filter-mapping>

过滤器的生命周期

  • 初始化:init()

  • 过滤:doFilter()

  • 销毁:destroy()

初始化参数:

1.配置<init-param>元素

<filter>
<init-param>
    <param-name>Encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>

2.读取过滤器的初始化参数

init(FilterConfig fConfig)  {
    String encoding=fConfig.getInitParameter("Encoding");
}

多个过滤器会形成过滤器链,根据过滤器的配置,按照先后顺序执行。

如果没有配置,则按照过滤器名称的字符a-z顺序执行。

过滤器将所有的接收字符串转换为utf-8类型示例如下:

@WebFilter("/api/*")
public class SetCharacter implements Filter {
​
    public void init(FilterConfig config) throws ServletException {
        System.out.println("this is init");
​
    }
​
    public void destroy() {
        System.out.println("this is destroy");
    }
​
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //放行
        chain.doFilter(request, response);
    }
}

WebFilter("/*")表示对所有请求进行过滤。

完全匹配:/index.jsp 目录匹配:/admin/* 扩展名匹配:*.do 全部匹配:/*

request.setCharacterEncoding("utf-8")在放行前,对所有的request请求进行字符串类型转换。

登录过滤示例:(注意登录的jsp页面和servlet种无需进行过滤)

@WebFilter(urlPatterns = {"/api/*","/pages/*"})
public class LoginFilter implements Filter {
​
    public void init(FilterConfig config) throws ServletException {
    }
​
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        
        HttpServletRequest request1 = (HttpServletRequest) request;
        HttpSession session = request1.getSession();
        HttpServletResponse response1 = (HttpServletResponse) response;
        if(session.getAttribute("user")!=null){
            //放行
            chain.doFilter(request, response);
        }else {
            response1.sendRedirect("/login.jsp");
        }
​
​
    }
​
    public void destroy() {
    }
​
}

注意:request和response要强转为HttpServlet的。当获取用户为空时,重定向到登录页面。

过滤器的应用场合

  • 对请求和响应进行统一处理

  • 对请求进行日志记录和审核

  • 对数据进行屏蔽和替换

  • 对数据进行加密和解密

EL与JSTL

EL表达式优化页面,JSTL标签优化页面

EL表达式

<table >        
    <c:forEach var="news" items="${list}">               
        <tr><td><c:out value="${news.title}" /></td></tr>        </c:forEach>
</table>

语法:${表达式} 例如:${username}

<body>
<%
request.setAttribute("key","值");
%>
表达式脚本输出 key 的值是:
<%=request.getAttribute("key1")==null?"":request.getAttribute("key1")%><br/>
EL 表达式输出 key 的值是:${key1}
</body>

EL操作符

操作符“.”

  • 获取对象的属性,例如:${news.title}

操作符“[]”

  • 获取对象的属性,例如:${news["title"]}

  • 获取数组或集合中的对象,例如:${newsList[0]}

EL运算符

运算符说明
( )改变执行的优先级,例如${3(4+5)}
+,-,*,/,%算术运算符,例如${3+2}
==,!=,>,>=,<,<=关系运算符,例如${a==b}或${a eq b}
&&,||,!逻辑运算符,例如${true&&false}
?:条件运算符,例如${a>b?1:2}
empty用于检测变量名是否为空,是否等于NULL,例如${empty name}

为了避免JSP混淆运算符和页面关键字,有替代写法:

关系运算符范例结果
== eq${5 == 5}或${5 eq 5}true
!= ne${5 != 5}或${5 ne 5}false
< lt${3 < 5}或${3 lt 5}true
> gt${3 > 5}或{3 gt 5}false
<= le${3 <= 5}或${3 le 5}true
>= ge${3 >= 5}或${3 ge 5}false

EL功能

  • 取得JavaBean对象的属性

    ${news.title}

  • 取得数组、List、Map类型对象的元素

    ${list[0]}

  • 使用各类运算符对原始数据进行简单处理

    ${totalRecordCount/pageSize}

  • 屏蔽一些常见的异常

    ${username}

  • 能实现简单的自动类型转换

    ${news}相当于(News)request.getAttribute("news")

EL访问作用域

request.setAttribute("news", news);

两种方式取数据:

使用Java小脚本:request.getAttribute("news");

使用EL表达式: ${ news } 或者 ${ requestScope.news }

作用域JAVA代码取值EL取值
请求作用域request.getAttribute("news");${ requestScope.news }
会话作用域session.getAttribute("username");${ sessionScope.username }
程序作用域application.getAttribute("count");${ applicationScope.count }
页面作用域pageContext.getAttribute("userNum");${ pageScope.userNum }

表达式搜索域数据的顺序

当四个域中都有相同的 key 的数据的时候,EL 表达式会按照四个域的从小到大的顺序去进行搜索

jsp页面:

<body>
<%
//往四个域中都保存了相同的 key 的数据。
request.setAttribute("key", "request");
session.setAttribute("key", "session");
application.setAttribute("key", "application");
pageContext.setAttribute("key", "pageContext");
%>
${ key }
</body>

servlet:

//传一般字符串(此处使用request传递)
String username = "zhangsan";
request.setAttribute("zhangsan",username);
​
//传对象(此处使用session传递)
Provider pro = new Provider();
pro.setProName("lisi_te");
request.getSession().setAttribute("lisi_te",pro);
​
//传集合(此处使用application传递)
List<Provider> list = new ArrayList<>();
Provider provider = new Provider();
provider.setProName("ww");
list.add(provider);
this.getServletContext().setAttribute("ww",list);

JSTL表达式

实现JSP页面中的逻辑控制

使用步骤

1.下载jstl.jar和standard.jar包

Index of /dist/jakarta/taglibs/standard/binaries

2.将这两个包复制到WEB-INF\lib目录

3.在JSP页面中添加指令

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

JSTL标签

标签库
标签库名称资源标示符(URI)前缀
核心标签库Oracle Java Technologies | Oraclec
国际化/格式化标签库Oracle Java Technologies | Oraclefmt
XML标签库Oracle Java Technologies | Oraclex
数据库标签库Oracle Java Technologies | Oraclesql
函数标签库Oracle Java Technologies | Oraclefn

核心标签库

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

国际化/格式化标签库

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

标签

<c:out/>标签

<c:out value="value" default="default" escapeXml="true|false "/>

value:需要输出显示的表达式

default:默认输出显示的值

escapeXml:是否对输出的内容进行转义

<c:set/>标签

作用:set 标签可以往域中保存数据 域对象.setAttribute(key,value); scope 属性设置保存到哪个域 page 表示 PageContext 域(默认值) request 表示 Request 域 session 表示 Session 域 application 表示 ServletContext 域 var 属性设置 key 是多少 value 属性设置值

<c:set  var="name"  value= "value" scope="域" />
保存之前:${ sessionScope.abc } <br>
<c:set scope="session" var="abc" value="abcValue"/>
保存之后:${ sessionScope.abc } <br>

<c:forEach/>标签

迭代标签,实现对集合的遍历

<c:forEach var="varName" items="items" varStatus="varStatus">
     ……
</c:forEach>

varName:集合中元素的名称

items:集合对象

varStatus:当前循环的状态信息,例如循环的索引号

for (int i = 1; i < 10; i++)

<table border="1">
<c:forEach begin="1" end="10" var="i">
<tr>
<td>第${i}行</td>
</tr>
</c:forEach>
</table>

begin 属性设置开始的索引

end 属性设置结束的索引

var 属性表示循环的变量(也是当前正在遍历到的数据)

<c:if/>标签

if 标签用来做 if 判断。 test 属性表示判断的条件(使用 EL 表达式输出)

<c:if test="condition" var="varName" scope="scope">
         ……
</c:if>
​
<c:if test="${ 12 == 12 }">
<h1>12 等于 12</h1>
</c:if>
<c:if test="${ 12 != 12 }">
<h1>12 不等于 12</h1>
</c:if>

varName:判断的结果

scope:判断结果存放的作用域

<c:url/>超链接标签

<c:url  value="url" />

<c:param/>参数标签

<c:param name="name"  value="value"/>

<c:import/>导入标签

<c:import url="URL" />

<fmt:formatDate/>格式化标签

实现格式化的日期和时间显示

<fmt:formatDate  value="date"  pattern="yyyy-MM-dd HH:mm:ss"/>
标签名称作用
<c:out />输出文本内容到out对象,常用于显示特殊字符
<c:set/>在作用域中设置变量或对象属性的值
<c:remove/>在作用域中移除变量的值
<c:if/>实现条件判断结构
<c:forEach/>实现循环结构
<c:url/>构造url地址
<c:param/>在url后附加参数
<c:import/>在页面中嵌入另一个资源内容
<fmt:formatDate/>格式化时间
<fmt:formatNumber/>格式化数字

分页查询

每次翻页的时候只从数据库里检索出本页需要的数据

步骤

  • 计算显示数据的总数量

  • 确定每页显示的数据量

  • 计算显示的页数

    页数=总数量/每页显示的数据量[+1]

  • 编写分页查询SQL语句

  • 实现分页查询

关键点

页数:总记录数/每页显示的记录数

整除:总页数=总记录数/每页显示记录数

不能整除:总页数=总记录数/每页显示记录数+1

编写分页查询SQL语句(limit)

select * from tableName where 查询条件

limit (当前页码-1)*页面容量, 页面容量

分页显示

  • 确定当前页

  • 设置首页、上一页、下一页、末页的页码

    还要对可能出现的异常进行控制

  • 首页与末页的控制

limit count(*) from smbms;

查找一共条数

-- 分页查询语法
-- 参数1:起始索引=(页码 - 1)*每页展示记录数
-- 参数2:查询返回记录数 = 每页展示记录数
select * from student limit 0,5;
​
-- 查询第一页数据,每页展示5条数据
select * from student limit 0,5;
​
-- 查询第二页数据,每页展示5条数据
select * from student limit 5,5;
​
-- 查询第三页数据,每页展示5条数据
select * from student limit 10,5

已经读到这里了,大佬点点关注喵~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值