第05讲:JSP

一、贯穿案例展示

楼宇管理列表

图片.png

二、切片2:楼宇管理列表

2.1、原型图(axure)

用axure现场画

2.2、实现需求

2.2.1、需求分析

需求分解:
1、设计基础样式的JSP文件(list.jsp)
2、在Servlet中获取楼宇的列表数据,并将该数据存放到request对象中
3、通过请求转发的方式,将请求转发到list.jsp
4、在list.jsp中,使用JSTL的核心标签库解析request对象中的楼宇列表信息,显示出页面效果

2.2.2、需求实现

在IDEA中通过Maven构建JSP的Web项目

参考:第04讲:tomcat和servlet

Ps:新创建的项目时,src/main/webapp/WEB-INFO/web.xml里面会报错,我们将错误的代码删掉

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"></web-app>

Ps:如果无法使用EL表达式则更改web.xml的web-app标签中的命名空间

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">
 
</web-app>

我们可以再尝试创建一个Servlet,首先需要在src\main目录下创建一个java文件夹

创建好之后该文件夹应该是蓝色的,如果是灰色的,则需要将其手动改成SourceFolder

修改方法:在文件夹上单机右键,以此选择Mark Directory as > Source Directory

图片.png

源代码

package manager;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 java.io.IOException;
import java.io.PrintWriter;@WebServlet(name = "Test", value = "/TestManager")
public class TestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码集
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setHeader("content-type", "text/html;charset=utf-8");
        resp.setContentType("text/html;charset=utf-8");//向页面输出内容
        PrintWriter pw = resp.getWriter();
        pw.println("你好 Servlet");
        pw.close();
    }
}

运行效果:

图片.png

参考代码
楼宇实体类
package entity;public class Building {
    private String no;
    private String unit;
    private String remark;
    ...
}
楼宇后台Servlet
package manager;import entity.Building;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 java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;@WebServlet(name = "Test", value = "/TestManager")
public class TestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码集
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setHeader("content-type", "text/html;charset=utf-8");
        resp.setContentType("text/html;charset=utf-8");
​
        req.setAttribute("list", initData());
        req.getRequestDispatcher("list.jsp").forward(req, resp);
    }private List<Building> initData(){
        Building b1 = new Building("20栋", "2单元", "无");
        Building b2 = new Building("21栋", "3单元", "无");
        Building b3 = new Building("22栋", "4单元", "无");List<Building> list = new ArrayList<Building>();
        list.add(b1);
        list.add(b2);
        list.add(b3);return list;
    }
}

前台JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <table>
    <c:forEach items="${list}" var = "li">
        <tr>
            <td>${li.no}</td>
            <td><c:out value="${li.no}"/></td>
            <td><c:out value="${li.remark}"/></td>
        </tr>
    </c:forEach>
    </table>
</body>
</html>

2.3、知识点补充

2.3.1、转发和重定向的区别

重定向与转发,都是用来实现web应用程序中资源的跳转。例如:从一个页面跳转到别一个页面,从一个servlet跳转到别一个servlet等。

转发与重定向的区别:
  1、转发是继续传递、处理同一个请求,在服务器端进行,浏览器显示旧请求URL
  2、重定向在客户端运行,会产生新请求,经过一次重定向后,浏览器会显示新url,UA EG reqeust内的对象无法使用。即目标资源不能获得reqeust属性值,而转发能获取。
   3、因为浏览器要发出一个新请求,所以重定向速度比转发慢。
   
在实际开发中转发和重定向选择的原则:
   1、优先选择转发,因为转发效率更高
   2、在同一个web应用程序的两个请求间传递数据时,在转发与重定向之间,只能通过转发实现。
   3、如果需要跳转到其他服务器上的资源,如:http://www.woniuxy.com则必须使用重定向

2.3.2、什么是JSP

JSP(Java Server Pages)是JavaWeb服务器端的动态资源。它与html页面的作用是相同的,显示数据和获取数据。可以把JSP当做一个Servlet,处理客户端请求,JSP负责页面显示和数据提交。

JSP的组成

JSP页面组成:html+javascript+css+JAVA代码

图片.png

2.3.3、EL概述

Expression Language

EL的作用

EL(Expression Language)是一门表达式语言,EL无法处理逻辑,只负责数据显示。等价于<%=%>

EL的格式

格式:${…}

2.3.4、JSTL概述

JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!EL负责显示数据,JSTL负责控制逻辑

JSTL使用

1 javaWeb项目中导入jstl依赖的jar包

2 使用taglib指令导入标签库

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
语法解析:
 prefix="c":指定标签库的前缀,这个前缀可以随便给值,但大家都会在使用core标签库时指定前缀为c;
 uri="http://java.sun.com/jstl/core":指定标签库的uri,它不一定是真实存在的网址,但它可以让JSP找到标签库的描述文件;
常用的JSTL标签
<!-- 逻辑判断 -->
<c:if test="条件">
​
</c:if>
​
<!-- 选择分支 -->
<c:choose>
    <c:when test="条件1"></c:when>
    <c:when test="条件2"></c:when>
    <c:when test="条件3"></c:when>
    <c:when test="条件4"></c:when>
    <c:when test="条件5"></c:when>
    <c:otherwise></c:otherwise>
</c:choose>
​
<!-- 循环 -->
<c:forEach var="循环变量" begin="起始值" end="结束值" step="步阶">
    循环操作
</c:forEach>
​
<!-- 循环 -->
<c:forEach var="循环变量" items="要循环的数组或集合">
    循环操作
</c:forEach>

2.3.4、域对象

request是域对象!在JavaWeb中一共四个域对象,其中ServletContext就是域对象,它在整个应用中只创建一个ServletContext对象。request其中一个,request可以在一个请求中共享数据。

ServletRequest:一个请求会创建一个ServletRequest对象,如果在一个请求中经历了多个Servlet,那么多个Servlet就可以使用request来共享数据。

HttpSession:一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共享session中的数据;

域方法常用的方法:

void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:servletContext.setAttribute(“xxx”, “XXX”),在request中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;
​
Object getAttribute(String name):用来获取request中的数据,当前在获取之前需要先去存储才行,例如:String value = (String)request.getAttribute(“xxx”);,获取名为xxx的域属性;
​
void removeAttribute(String name):用来移除request中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;
​
Enumeration getAttributeNames():获取所有域属性的名称;

2.3.5、session

session概述

Session是一种保存上下文信息的机制,它针对每一个用户,在服务器端开辟一块存储空间来存入用户的会话状态,通过SessionId来区分不同的客户。使用session对象存储特定用户会话信息,当用户在应用程序web页面之间跳转时,存储在session对象中的变量不会丢失,直到会话结束。

session常用方法
方法描述
boolean isNew()判断当前会话对象是否是新创建的会话
Object getAttribute(String name)根据指定名称从会话中取出某个属性的值
void setAttribute(String name,Object value)根据指定名称将某个对象存放到会话中
void removeAttribute(name)从会话中移除指定名称的属性
String getId()获取会话id
void invalidate()使会话失效
void setMaxInactiveInterval(int interval)设置会话超时的时间秒值
session会话的超时管理

在HTTP协议中,web服务器无法判断当前的客户端浏览器是否还会继续访问,也无法检测客户端浏览器是否关闭。即使客户已经离开或关闭了浏览器,web服务器还要保留与之对应的session对象。随着时间的推移,服务器端内存中会累积大量不被使用的session对象。为此web服务器采用"超时限制"的办法来判断客户端是否还在继续访问,如果某个客户端在一定时间内没有发出后续请求,web服务器会认为客户端已经停止活动,并结束本次会话。

一般的web容器,默认的会话时间间隔30分钟

设置session有效时间的方式:
 1、在页面中设置
     HttpSession session=request.getSession(true);  
     session.setMaxInactiveInterval(900);//此处的900单位是秒
 2、在web.xml中设置
      <session-config>
            <session-timeout>15</session-timeout>
        </session-config>
 3、在tomcat中设置
     在tomcat目录下conf/web.xml中找到<session-config>元素,tomcat默认设置是30分钟,只要修改这个值就可以了
     
 注意:如果上述三个地方如果都设置了,有个优先级的问题,从高到低:(1)--(2)---(3)

2.3.6、过滤器

过滤器概述

Filter,过滤器,顾名思义,即是对数据等的过滤,预处理过程。为什么要引入过滤器呢?在平常访问网站的时候,有时候发一些敏感的信息,发出后显示时 就会将敏感信息用*等字符替代,这就是用过滤器对信息进行了处理。这只是一个简单的例子,当然,过滤器那么强大,它的功能也不可能局限于此,它不仅能预处 理数据,只要是发送过来的请求它都是可以预处理的,同时,它还可以对服务器返回的响应进行预处理,这样,大大减轻了服务器的压力。例如,实现URL级别的 权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。下面来详细介绍一下过滤器。

Filter对从客户端向服务器端发送的请求进行过滤,也可以对服务器端返回的响应进行处理。它使用户可以改变一个request和修改一个 response.。Filter 不是一个servlet,它不能产生一个response,但是它能够在一个request到达servlet之前预处理request,也可以在 response离开servlet时处理response。换句话说,filter其实是客户端与servlet中间的一个传递者,并且它可以对要传递 的东西进行修改。

图片.png

注意:过滤器是用来拦截请求和响应的,不能产生响应,而servlet是用来处理请求并产生响应的。

过滤器工作原理:
    a、当客户端发生请求后,在HttpServletRequest 到达Servlet 之前,过滤器拦截客户的HttpServletRequest 。 
    b、根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。 
    c、在过滤器中调用doFilter方法,对请求放行。请求到达Servlet后,对请求进行处理并产生HttpServletResponse发送给客户端。
    d、在HttpServletResponse 到达客户端之前,过滤器拦截HttpServletResponse 。 
    e、根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。
    f、最后,HttpServletResponse到达客户端。
常用方法描述
init()初始化参数,在创建Filter时自动调用。当我们需要设置初始化参数的时候,可以写到该方法中
doFilter()拦截到要执行的请求时,doFilter就会执行。这里面写我们对请求和响应的预处理。
destroy()在销毁Filter时自动调用
使用过滤器统一配置servlet编码格式
使用步骤:
  1) 定义类实现javax.servlet.Filter接口
  2) 实现类中的doFilter() 执行过滤器相关的处理
  3) 使用@WebFilter注解,或添加web.xml中的映射配置信息
创建编码集过滤器
package filter;
​
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
​
@WebFilter(filterName = "encodingFilter", urlPatterns = {"/*"})
public class EncodingFilter implements Filter {
​
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("*************in filter*************");
        //设置编码集
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        //将请求发送给下一个过滤器,如果后续没有其他相关的过滤器则到达所请求的资源[servlet、jsp、html]
        filterChain.doFilter(req, resp);
    }
    public void init(FilterConfig filterConfig) throws ServletException {
​
    }
    public void destroy() {
​
    }
}

也可以使用在web.xml中注册filter的方式来使用过滤器,方法如下:

图片.png

使用过滤器实现登录验证

配置过滤器实现登录拦截功能,未登录时,通过url地址栏输入任一地址都将回到登录界面,登录后则正常执行访问资源

过滤时要把登录页面和静态资源放行,否则无法访问

// 获得request、response、session对象
HttpServletRequest res = (HttpServletRequest) request;
HttpServletResponse rep = (HttpServletResponse) response;
HttpSession session = res.getSession();

// 获得地址栏中的路径
String path = res.getRequestURI();

// 判断该路径中是否包含指定信息,包含则放行
if (path.contains("/login.jsp") || path.contains("/loginServlet") || path.contains("/css/") ||path.contains("/js/") || path.contains("/images/")) {
		// 放行
		chain.doFilter(request, response);
		return;
}

//判断登录时保存的session是否存在
if (session.getAttribute("user") == null) {
	// 未登录,重定向到登录页面
	rep.sendRedirect(res.getContextPath() + "/login.jsp");
} else {
	// 登录过将请求放行
	chain.doFilter(request, response);
}

2.3.7、三层架构&MVC开发模式

三层架构

在实际的开发中,java编程语言设计程序会使用javaEE三层架构这种方式。

什么是三层架构:

图片.png

优点:
  1、开发人员可以只关注整个结构中的其中某一层;
  2、可以很容易的用新的实现来替换原有层次的实现;
  3、可以降低层与层之间的依赖;
  4、有利于标准化;
  5、利于各层逻辑的复用。
  6、结构更加的明确
  7、便于维护
  
缺点:
	1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
	2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
MVC开发模式

MVC不是设计模式,是一个比设计模式更大一点的模式,称作设计模式不合理,应该说MVC它是一种软件开发架构模式,它包含了很多的设计模式。

MVC(Model-View-Controller) 模式的基本思想是:数据、显示和处理(业务)相分离。

模型(Model)负责数据管理,
视图(View)负责数据显示,
控制器(Controller)负责业务逻辑和响应策略。

图片.png

我们打开浏览器,输入网址,就是到服务器中请求页面(JSP也可能是别的),然后显示到浏览器上,然后通过点击JSP页面上的内容,提交请求,到服务器中,也就到了Control(Servlet)这一块,Servlet通过分析请求,知道用户需要什么,需要数据,那么就通过Model,从数据库拿到数据,在将数据显示在JSP中,在将JSP发送回浏览器,显示在用户看,所以我们经常说,JSP就是View层,给用户看的,Servlet作为控制流程,而编写操作数据库代码,业务逻辑代码就属于Model。这就是MVC的应用。

MVC模式使用原则:
 请求必须交给控制器
 视图只作界面的展示
 模型负责操作数据库,数据需要展示到界面则使用控制器进行共享
三层和mvc的区别

MVC和三层是两个毫无相关的东西,经典三层架构是一种分层思想,将开发模式分为了这三层,每个人根据自己的专长,开发不同的模块,比如,前端工程师,那么就专研表示层即可,想办法如何让页面变的更好看,如何吸引别人,而有些专门做数据库工作的人,就可以只关注操作数据库的活,如何让查询更加快速有效,而不必关注数据该如何显示这种问题。这就是分层带来的巨大好处。   而MVC是一种软件开发模式,目的是让HTML代码和业务逻辑代码分开,让代码看起来更加清晰,便于开发。 ​ 硬说他们有关系的话,只能说他们有共同的点,分层,解耦。

MVC架构下程序结构如下:

实际项目中的包命名结构,其也是按照三层架构思想来进行编写代码的。

图片.png

2.4、小结

现场提问

1、EL表达式的作用是什么?(答:负责数据显示,格式${…})
2、JSTL中常用的标签库有哪几个?(choose-when-otherwise、if、forEach)
3、request和session的区别是什么?
4、如何设置session的超时时间?
5、过滤器需要实现Java中的哪一个包下的什么接口?(答:javax.servlet.Filter接口)
6、简述你所理解的MVC软件开发模式

三、课程小结

3.1、知识框架图

现场提问,用XMind现场总结,再次加深学生印象

图片.png

3.2、课后作业

需求定义

开发一个用户注册的功能

需求分解

参考上一章

原型设计

参考上一章

参考文献

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值