Java:51-JSP核心技术

JSP核心技术

JSP的概述(熟悉)-------------------------
JSP的概念:
JSP是Java Server Pages的简称,跟Servlet一样可以动态生成HTML响应, JSP文件命名为xxx.jsp
与Servlet不同,JSP文件以HTML标记为主,然后内嵌Java代码段,用于处理动态内容
JSP的示例:
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html> 
    <head>   
        <title>Hello Time</title> 
    </head> 
    <body>  
        现在的时间是:<%= new Date()%> 
    </body>
</html>
JSP与Servlet的关系:

在这里插入图片描述

本来由于Servlet要有界面到网页时,只能通过IO流(如打印流PrintWriter)
虽然有个文档,类似于网络编程的那个文档,但是是空的,这时,若要有大量的界面,那么就要输出大量的字符串
IO流需要对应的标签,用字符串包括,非常的麻烦
于是就有了Jsp,每一个JSP页面都会被Web容器编译成一个Java类,供web容器调用,并且生成HTML页面回馈给用户
然后编译成.classjsp = java + html
servlet = java + out.print(html),IO流中放html
JSP是Servlet技术的扩展,本质上就是Servlet的简易方式,JSP编译后是"类servlet"
具体过程如下:
客户端发送请求给web容器
web容器将jsp首先转译成servlet源代码,他的内容html就放在IO流中(这里直接帮我们写了html代码)
否则平常的话,我们写Servlet还需要输出大量的html代码
html中间有我们的java代码操作,如表达式的代码直接进行连接
而全局的则在对应Servlet方法外,局部的在对应Servlet方法内,表达式的代码直接连接html,即IO流的输出
有多个输出,且局部的会有位置顺序,只所以可以这样
是因为Jsp中的java代码段由不同的符号包括,在转译时
就会判断,然后服务器就自动根据出现的不同结果来生成Servlet的一系列代码
可以看一下转译的部分源代码:

在这里插入图片描述

可以看到全局的在类里面
对应方法:

在这里插入图片描述

在这里插入图片描述

可以看到局部在有顺序的放入,在方法里面

在这里插入图片描述

可以看到在IO的输出流里面直接连接输出,最后将对应文档显示在客户端,如浏览器
下面的就是平常Servlet操作了
web容器将servlet源代码编译成.class 文件
web容器执行.class 文件
web容器将结果响应给客户端(文档中IO流输出的结果),因为读取文档

在这里插入图片描述

由着可以得出,tomcat需要jdk的运行环境,即必须要jre,jdk的其他东西可以不要
实际上无论还是什么操作,如反射,都是class在运行的,我们java都是编译过去
且可以看出Jsp与Html底层有很大的不同,html是不用编译直接执行的,jsp需要转译和编译
java,jsp:需要编译运行
mysql,html,css,js:都直接运行,基本一行一行读取,从上到下
JSP的语法(熟悉):
注意:Jsp与Java一样需要重新部署才可,因为是先放到服务器内存中的,与html不一样,html是放在服务器文件等待读取的
JSP语法结构:
声明区,程序,代码区,表达式,注释,指令和动作,内置对象
声明区:
基本语法:
当Jsp是要读取的文件时,下面的符号,Servlet可以判断,并做出对应转化执行(html可能不会)
<%! %>说明:
可以定义全局变量、方法、类
<%!    
    int i;  
public void setName(){… …}
%>
程序代码区:
基本语法:
<%程序代码区%>
说明:可以定义局部变量以及放入任何的Java程序代码
<%    
int j;   
for (int k=0; k<10; k++) {        … …   }
%>
表达式:
基本语法:
<%=… …%>
说明:可以输出一个变量或一个具体内容,但=后面必须是字符串变量或者可以被转换成字符串的表达式
注意:不需要以" ; " 结束,只有一行
<%=
    "hello world"
    %>
<%=
    i+1
    %>
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试变量的声明和打印</title>
    <%!
        int ia; // 这是一个全局变量
        //类方法
        public void show() {
            System.out.println("这是全局方法!");
        }
        //内部类
        public class MyClass {
            {
                System.out.println("这是一个全局类哦!");
            }
        }
    %>

    <%
        //相当于在main方法里
        int ib = 20;  // 这是一个局部变量

        for (int i = 0; i < 3; i++) {
            System.out.println("随便放入Java程序代码吧!");
        }
    %>
</head>
<body>
<!-- 相当于直接计算 -->
<%= ia+1 %>  <%-- 1 --%>
<%= ib %>    <%-- 20 --%>
<%= "我就暂时写到这里吧!"%>  <%-- 我就暂时写到这里吧!,这里是jsp注释的方法,底层不识别--%>
</body>
</html>

注意:在转译时,是不会判断是否错误的,即先全部按照规则变成java,即可以分开写,如
<%! public void f(){
    %>
<%!
}
%>
<!--或者-->
<%
int a=%><%3;%>
<!--上面可以这样写的-->
<!--那是因为java可以这样
public void f(){
//其他操作

} 隔开
int a= 3 隔开,但java代码块之间不可换行
换行的话会被 out.write占据,使得报错,因为我们是要变成java代码
所以java代码要识别这个换行
-->
<!--下面不可以,因为只算作一行-->
<%=
    6+
    %>
<%=
    4
    %>
<!--那是因为这里直接当作括号了,即(6+),和(4)-->
上述结果的出现,主要是位置问题,在类里面,没有使用out.write方法,在方法里有使用out.write方法
又因为Jsp的每个java代码块之间的换行都会被这个使用
使得有些不可操作,如赋值时,中间不可有该方法,但其他合理的可以有,如循环时可以有
简单来说:将Jsp的所有内容,进行转译表示成java代码后(java代码块里是java操作)
再编译,即这个编译需要识别java里的错误的,即需要合理的位置
最终java的执行,使得out.write方法对页面的渲染操作,看如下案例题目对这的具体操作
案例题目:
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现表格的绘制</title>
</head>
<body>
<table>
    <tr>
        <td>id</td>
        <td>name</td>
        <td>age</td>
        <td>salary</td>
    </tr>
    <%
        for (int i = 1; i < 6; i++) {
    %>
    <tr>
        <td> <%= i %> </td>
        <td> <%= i %> </td>
        <td> <%= i %> </td>
        <td> <%= i %> </td>
    </tr>
    <%
        }
    %>
</table>
</body>
</html>

源代码循环如下:

在这里插入图片描述

输出了多次,即文档内容又多了起来
注释:
格式:
<!--… …-->   HTML文件的注释,浏览器可以查看到,到java代码里面的out.write方法里面可以看到
<%--… …--%>   JSP文件的注释,浏览器看不到,到java代码里面不可以看到
<%//… …%>     Java语言中的单行注释,浏览器看不到,到java代码里面可以看到
<%/*… …*/%>   Java语言中的多行注释,浏览器看不到注释的内容不会被执行,到java代码里面可以看到
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注释的测试</title>
</head>
<body>
<!-- 这是HTML文件中的注释方式,浏览器是可以看到的 -->
<%-- 这是JSP文件中的注释方式,该方式浏览器是看不到的 --%>
<%
    // Java语言中的单行注释   浏览器看不到哦
    /* Java语言中的多行注释   浏览器看不到哦! */
%>
</body>
</html>

指令和动作:
指令格式:
<%@指令 属性=“属性值”%>
指令的属性可以设定多个
JSP常用指令有:page、taglib、include
page指令:
page指令用于导包和设置一些页面属性,常用属性如下:

在这里插入图片描述

编码中间可以操作,最后解码交给显示,上面导入包的Jsp格式会被转译为java的导包
上面的其他转译,一般都是会到Java代码中显示,有些没有,这是转译的底层操作
注意:上面的pageEncoding就是字面的意思,在java中,改变他保存就是当前页面内容的编码格式,可以参照idea右下角的显示,可以发现发生了改变(可能不同的idea有所不同,即并不保证是这样的)
<%@ page import="java.util.List" %>
<%@ page import="java.util.LinkedList" %>
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<html>
<head>
    <title>page指令的使用</title>
</head>
<body>
<%
    List<String> list = new LinkedList<String>();
%>
</body>
</html>

taglib指令:
taglib指令用来扩展JSP程序的标签元素,引入其他功能的标签库文件:
<!-- prefix属性用于指定库前缀 -->
<!-- uri属性用于指定库的标识 -->  
<%@taglib uri="tagLibary" prefix="prefix"%>
include指令:
include指令用于引入另一个JSP程序或HTML文件等,格式如下:
<%@include file="被包含的文件地址"%>
    <!--就是在这个位置放入指定的jsp内容,使得title谁前谁显示,后面的多余的只有body内容显示,且分先后-->
注意:Jsp的转译也是一行一行的,即只要符合就可以识别,且也是从上往下的的放入具体位置
JSP引擎会在JSP文件的转换时期先把file属性设定的文件包含进来,然后开始执行转换及编译的工作
jsp:include/jsp:param:
jsp:include动作用于引入另一个JSP程序或HTML文件等
执行到include时,被include的文件才会被编译
如果include的是jsp文件,那它不会被转换成Servlet文件
<jsp:include page="URLSpec" flush="true"/>
<jsp:include page="URLSpec" flush="true"> 
    <jsp:param name="key" value="value"/>
</jsp:include>
include指令和include动作的区别:
include指令是在JSP程序的转换时期就将file属性所指定的程序内容嵌入再编译执行(静态包含)
include动作在转换时期是不会被编译的,只有在客户端请求时期被执行到才会被动态的编译载入(动态包含,推荐)
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 表示包含或引入head.jsp文件 include指令的方式  静态包含
先包含,然后转译,再编译,运行,只有一个class,其中资源不可改变了,因为包含了--%>
<%--<%@ include file="head.jsp"%>--%>
<%-- include动作的方式  动态包含 推荐
一起转译,在编译,运行时有两个class,类似于java导入类,使用了类的信息,即class运行时操作,动态的改变--%>
<jsp:include page="head.jsp"></jsp:include>
<html>
<head>
    <title>文件引入的使用</title>
</head>
<body>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>被引入的通用文件</title>
</head>
<body>
    所有页面的公共头部部分就可以写在这里,然后让所有页面包含或引入该文件即可
</body>
</html>

jsp:forward/jsp:param:
forward动作用于在JSP中实现转发,将请求转发到另一个指定的JSP程序或者Servlet中处理:
<jsp:forward page="urlSpec" flush="true"/>
<jsp:forward page="urlSpec">       
    <!-- 用于指定参数和其对应的值 -->   
<jsp:param name="key" value="value"/>
</jsp:forward>
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP页面的转发实现</title>
</head>
<body>
<jsp:forward page="target.jsp">
    <jsp:param name="name" value="zhangfei"/>
</jsp:forward>
<%-- 设置属性,即给请求信息添加属性,保存在request里面--%>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>转发的目标文件</title>
</head>
<body>
<h1>服务器转发后执行这里的代码哦!</h1>
<%= "获取到的数值为:" + request.getParameter("name")%><br/>
<%--实际上由于有两个class,即两个servlet,即转发时
    可以得到request的值,由于共享,即扩展,所以也可以得到对应name的值 --%>
</body>
</html>

JSP内置对象(重点):
基本概念:
在JSP程序中有9个内置对象由容器为用户进行实例化,程序员可以不用定义就直接使用这些变量
在JSP转换成Servlet后,会自动追加这些变量的定义,使用内置对象可以简化JSP的开发
对象名称:

在这里插入图片描述

out内置对象:
out内置对象是一个缓冲的输出流,用来给客户端输出信息
常用方法如下:

在这里插入图片描述

//缓冲区是一个大小的存储,真正的清除是使用的数据
//注意:其实上面的clearBuffer不会将数据输出到客户端,只所以上面说把数据输出到客户端这样写,是因为如下
//cleraBuffer和clear单独作用时,都是清除缓冲的数据
//若和flush一起使用时,则不同,只所以这样,是因为flush的底层操作
//当flush写在clear前面时,clear的作用,就是关闭out对象,而不是清除缓冲数据
//而放在clearBuffer前面,则还是原来的作用,所以说,在大多数情况下
//clearBuffer是不会导致out对象的关闭,即可以说是后面的代码是可以把数据输出到客户端的
//而clear则会把out对象关闭,即后面的代码不可以把数据输出到客户端了
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>out内置对象的使用</title>
</head>
<body>
<%
    out.println("<h1>");
    out.println("Hello World!");
    out.println("</h1>");
    //out.close();

    int bufferSize = out.getBufferSize();
    System.out.println("缓冲区的总大小是:" + bufferSize);
    int remaining = out.getRemaining();
    System.out.println("缓冲区的剩余字节数为:" + remaining);
    System.out.println("已经使用的字节数为:" + (bufferSize - remaining));

    out.clear(); // 清除缓冲区  数据不会输出
    remaining = out.getRemaining();
    System.out.println("缓冲区的剩余字节数为:" + remaining);
%>
</body>
</html>

request内置对象:
request对象封装的是调用JSP页面的请求信息,它是HttpServletRequest接口的一个实例
该对象的属性值只在一个请求中保存
常用方法如下:

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>request内置对象的使用</title>
</head>
<body>
<%
    String serverName = request.getServerName();
    System.out.println("获取到的服务器名称为:" + serverName);
    int serverPort = request.getServerPort();
    System.out.println("获取到的服务器端口号为:" + serverPort);
    // 通过内置对象设置属性信息,也就是存储数据
    request.setAttribute("name", "guanyu");
%>
<%-- 实现转发效果,也就是服务器跳转 --%>
<jsp:forward page="requestTarget.jsp"></jsp:forward>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>获取request对象中的属性值</title>
</head>
<body>
<%= "获取到的属性值为:" + request.getAttribute("name")%>  <%--  guanyu --%>
</body>
</html>

response内置对象:
response对象用于给客户端相应输出处理结果,它是HttpServletResponse接口的一个实例
经常用于设置HTTP标题,添加cookie、设置响应内容的类型和状态、发送HTTP重定向和编码URL
常用方法如下:

在这里插入图片描述

<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %><%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>response内置对象的使用</title>
</head>
<body>
<%
    // 表示每隔1秒刷新一次
    response.addHeader("refresh", "1"); 
    //添加的信息根据对应名称操作,当然也可以随便写,只是浏览器不识别而已
    //refresh 刷新的意思,每隔1秒刷新一次,浏览器会识别这个refresh属性,使得当前页面进行每隔一秒刷新操作
    // 获取当前系统时间
    Date d1 = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String format = sdf.format(d1);
%>
<%= "当前时间为:" + format %>
</body>
</html>

session内置对象:
session对象表示浏览器和服务器之间的一次会话,一次会话可以包含多次请求
在多次请求之间可以借助session对象存储信息,它是HttpSession类型的一个实例
该对象的属性值在一次会话范围中保存,保存在服务器端,只要不关闭服务器,默认半个小时内都可以访问,即30分钟
常用方法如下:

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>session内置对象的使用</title>
</head>
<body>
<%
    session.setAttribute("name", "liubei");
    System.out.println("session内置对象中的数据设置成功!");
%>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>获取session内置对象中的数据</title>
</head>
<body>
<%= "获取到的属性值为:" + session.getAttribute("name")%>
</body>
</html>

application内置对象:
application对象是一个web程序的全局变量,它是ServletContext类型的一个实例
在整个服务器上保存数据,所有用户共享
常用方法如下:

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>application内置对象的使用</title>
</head>
<body>
<%
    application.setAttribute("name", "zhaoyun");
    System.out.println("application内置对象中的数据设置成功!");
%>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>application内置对象的获取</title>
</head>
<body>
<%= "获取到的application内置对象的属性为:" + application.getAttribute("name")%> <%-- zhaoyun --%>
</body>
</html>

pageContext内置对象:
pageContext对象是PageContext类型的对象,可以使用这个对象来管理其他的隐含对象
只在一个页面中保存数据,即其他的请求就没有了

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>pageContext内置对象的使用</title>
</head>
<body>
<%
    pageContext.setAttribute("name", "huangzhong");
    System.out.println("pageContext内置对象中的数据设置成功!");
%>
<%= "获取到的pageContext内置对象中的属性值为:" + pageContext.getAttribute("name")%>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>pageContext内置对象属性的获取</title>
</head>
<body>
<%= "获取到的pageContext内置对象中的属性值为:" + pageContext.getAttribute("name")%> <%-- null --%>
</body>
</html>

exception内置对象:
exception 对象是Throwable的实例,表示的是JSP的异常信息
如果要使用它,必须将对应页面page指令的isErrorPage属性设置成true
单个页面的处理方式
<%@page errorPage="error.jsp" %>
在web.xml中配置统一的异常处理页面:
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <error-page>
        <exception-type>java.lang.Throwable</exception-type>
        <location>/error.jsp</location>
    </error-page>
    <!--
    底层通过反射创建对应异常对象,当服务器的Servlet发生错误时
    就不会将原来的错误信息输出,而是转发到location的路径下
    会检查是否有error-page这个元素,当有这个配置文件,则会进行转发,否则输出原来错误信息,最后响应给页面
    -->
</web-app>
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="error.jsp" %><%--指定异常的页面,当发生错误时
    将这个页面信息给文档,而不是将原来默认的信息给文档
    若和配置文件一起,则因为就近原则,使用这个文件,导致不读取配置文件了,否则读取配置文件
    --%>
<html>
<head>
    <title>exception内置对象的使用</title>
</head>
<body>
<%
    int ia = 10;
    int ib = 0;
    System.out.println(ia / ib); // 算术异常
%>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>发生另外一种异常的页面</title>
</head>
<body>
<%
    int[] arr = new int[5];
    System.out.println(arr[5]); // 数组下标越界异常
%>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isErrorPage="true" %> <%--将这个页面设置为错误页面,别人发生错误时
    <%@ page errorPage="error.jsp" %>使用这个指向
    则会使用这个页面
    若没有设置true,则下面的exception就会报错,不可使用
    --%>
<html>
<head>
    <title>异常处理的页面</title>
</head>
<body>
<%
    if (exception != null) {
        out.println("异常的错误信息为:" + exception.getMessage()); //异常信息
    }
%>
</body>
</html>

JavaBean组件(熟悉)-----------------------------
基本概念:
JavaBean 是使用 Java 语言开发的一个可重用的组件,在 JSP 开发中可以使用 JavaBean 减少重复代码
使整个 JSP 代码的开发更加简洁
JavaBean本质上就是Java类,通常要求如下:
属性:全部私有化,通过get和set方法进行访问
方法:必须是public关键字修饰。
构造器 :必须有无参构造方法
package com.lagou.demo02;

public class Student {
    private int id;
    private String name;

    public Student() {
    }

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

<%@ page import="com.lagou.demo02.Student" %><%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JavaBean组件的使用</title>
</head>
<body>

<%-- 表示创建Student类型的对象由student引用变量负责记录  有效范围是当前页面
    相当于给你创建对象,不用自己创建对象了,即Student student = new Student();
    所以Student这个变量就使用了,即不可再用Student这个变量了,否则报错
    --%>
<jsp:useBean id="student" scope="page" class="com.lagou.demo02.Student"/>
<%-- 表示将student对象中名字为id的属性值设置为1002 
    --%>
<jsp:setProperty name="student" property="id" value="1002"/>
    <%-- 表示将student对象中名字为name的属性值设置为guanyu--%>
<jsp:setProperty name="student" property="name" value="guanyu"/>
<%--
     注意:id和name是student引用的属性值,即成员变量的名字,不可忽略大小写
    使用上面相当于调用对应的setxxx,xxx是他们对应成员变量的首字母忽略大小写的名字
    如setId,setid等等,setName,setname等等,实际上是成员变量对应set的首字母大小写忽略
    --%>
<%
    // 创建Student类型的对象并设置成员变量的数值
    //Student student = new Student(); 上面若创建对象,则这个名字不可使用
    //student.setId(1001);
    //student.setName("zhangfei");
%>

<%--<%= "获取到的学号是:" + student.getId() %>   &lt;%&ndash; 1001 1002 &ndash;%&gt;
<%= "获取到的姓名是:" + student.getName() %> &lt;%&ndash; zhangfei guanyu &ndash;%&gt;--%>
    <%-- 表示获得student对象中名字为id的属性值 
    --%>
学号是:<jsp:getProperty name="student" property="id"/><br/>
     <%-- 表示获得student对象中名字为name的属性值 
    --%>
姓名是:<jsp:getProperty name="student" property="name"/><br/><%--其中property的值也可以是class
    获得对应Class对象,返回class com.lagou.demo02.Student
    --%>
    <%-- 
    注意:id和name是student引用的属性值,即成员变量的名字,不可忽略大小写
    获取对应值,getxxx,xxx首字母大小写忽略
    实际上是成员变量对应get的首字母大小写忽略
    如getId,getid,getName,getname等等
    --%>
    
    
    <%--上面无论是set还是get只对名称要求,内容不做要求,如getId一般内容是return id
    但是可以改成return 4,不会报错
    --%>
</body>
</html>

使用方式:
使用jsp:useBean的方式创建javaBean实例:
<jsp:useBean id=“对象名” scope=“保存范围 class=“包名.类名” />
保存范围有:page|request|sessin|application,默认为page范围
使用jsp:setProperty的方式设置javaBean的属性值:
<jsp:setProperty name="对象名" property="属性名" value="属性值" param="参数名"/>
<%--注意:value和param不能一起,否则报错--%>
使用jsp:getProperty的方式获取javaBean的属性值:
<jsp:getProperty name="对象名" property="属性名"/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>实现向JavaBean组件传入参数的使用</title>
</head>
<body>
<form action="bean2.jsp" method="post">
    学号:<input type="text" name="id1"/><br/>
    姓名:<input type="text" name="name1"/><br/>
    <input type="submit" value="向JavaBean组件传参"/>
</form>
</body>
</html>
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现前端页面传入过来参数的接收和设置</title>
</head>
<body>
<jsp:useBean id="student" scope="session" class="com.lagou.demo02.Student"/>
<jsp:setProperty name="student" property="id" param="id1"/>
<jsp:setProperty name="student" property="name" param="name1" value="1" />
<%--  
    注意:param需要其他请求信息的数据,即其他页面传过来的参数,且不 能和value一起,否则报错
因为他们都是对数据进行操作的,底层只能操作一个,若有多个,则会报错的
且要注意空格要写,你写是去,会提示你的,若执意运行,则报错
--%>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现JavaBean组件中对象属性值的打印</title>
</head>
<body>
<jsp:useBean id="student" scope="session" class="com.lagou.demo02.Student"/>
<%-- 获取名字为student对象中属性为id的数值并打印 --%>
经过参数赋值后获取到的学号是:<jsp:getProperty name="student" property="id"/><br/>
经过参数赋值后获取到的姓名是:<jsp:getProperty name="student" property="name"/><br/>
<%--
 对于jsp:useBean的底层,他是会先去调用对应的getAttribute("student"))方法,来获得Student对象
 若没有,则创建该类型对象,然后设置进去,由于是地址,那么若有setProperty,则会设置值给这个对象
 所以若需要里面的东西,就要取出来,则必须还要使用jsp:useBean方式
 使得调用对应的getAttribute("student"))方法取出来
 --%>
</body>
</html>

上面取Student对象和设置对象和获得对象的底层代码如下:
首先取出对应对象,没有再创建,相当于是将对象设置到范围的对象中去,这里是Session对象

在这里插入图片描述

由于地址相同,然后设置值,那么地址的值发生改变,即设置了值,其中id1和name对应的方法是取请求信息的数据,然后设置

在这里插入图片描述

最后还要取,并调用对象的get方法来获得

在这里插入图片描述

这就是上面jsp:useBean的底层原理
在取的时候,后面有跟着范围,这个范围就是对应对象的范围,这里是Session对象
就是对Session对象的操作,即取出,设值,再取出,得值
就类似于session.setAttribute()和session.getAttribute(),他们都有一个类型来获得他们,就如上面的student
所以这就是为什么需要两个jsp:useBean的原因了
保存范围:
JavaBean的保存范围有page、request、session以及application,默认是page范围
删除方式:
<% 
内置对象.removeAttribute("JavaBean的名字"); 
%>
<%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>实现JavaBean组件数据的删除</title>
</head>
<body>
<%
    // 表示从session对象中删除名字为student的属性
    session.removeAttribute("student");
%>
<%= "删除数据成功!" %>
</body>
</html>

MVC设计模式(重点)----------------------------
基本概念:
MVC是模型(Model)和视图(View)以及控制器(Controller)的简写
是一种将数据、界面显示和业务逻辑进行分离的组织方式,这样在改进界面及用户交互时,不需要重新编写业务逻辑
从而提高了代码的可维护性
M:主要用于封装业务数据的JavaBean(Bean) 和 业务逻辑的JavaBean(Service)及访问数据库的DAO对象
V:主要负责数据收集 和 数据展现,通常由JSP文件完成
C:主要负责流程控制 和 页面跳转,通常由Servlet完成
基本模型:

在这里插入图片描述

服务器让请求到Servlet,然后转发给Jsp,然后Jsp自己创建Servlet,最后响应,第一次都是由服务器来交给的
即找到对应的文档(直接的访问)或本地资源(Jsp)
package com.lagou.demo03.bean;

public class User {
    private int id;
    private String userName;
    private String password;

    public User() {
    }

    public User(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

package com.lagou.demo03.dao;

import com.lagou.demo03.bean.User;

public interface UserDao { //主要用来维护的,若用类的话,由于只能继承一个
    //即其他类来继承这个时,就不能继承其他类了,虽然可以实现接口,但这个都变为类了,为什么其他的要用接口呢
    //所以最好还是接口
    //为了可以使得留有余地,即最好还是变为接口,因为父类指向子类时,最后还是子类的操作,父类就不操作了
    //但是类也是由好处的,可以自己操作自己,而接口不能
    // 自定义抽象方法描述登录功能的实现
    public abstract User userLogin(User user);
}

package com.lagou.demo03.dao;

import com.lagou.demo03.bean.User;
import com.lagou.demo03.util.DbUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDaoImp implements UserDao {
    @Override
    public User userLogin(User user) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            // 1.获取数据库连接
            connection = DbUtil.getConnection();
            // 2.准备sql语句
            String sql = "select * from t_user where userName = ? and password = ?";
            // 3.执行sql语句后获取结果并返回
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, user.getUserName());
            preparedStatement.setString(2, user.getPassword());
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                User tu = new User(resultSet.getString("userName"), resultSet.getString("password"));
                return tu; // 表示查找成功
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 4.释放相关的资源
            try {
                DbUtil.closeResource(connection, preparedStatement);
                if (null != resultSet) {
                    resultSet.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return  null; // 表示查找失败
    }
}

package com.lagou.demo03.service;

import com.lagou.demo03.bean.User;
import com.lagou.demo03.dao.UserDao;
import com.lagou.demo03.factory.UserDaoFactory;

public class UserService {
    private UserDao userDao;

    public UserService() {
        this.userDao = UserDaoFactory.getUserDao();
        //这是是工厂模式,静态的
    }
    //这是为了不用在主程序里创建对象,如果创建对象,那还要这个类干什么呢
    /**
     * 自定义成员方法实现根据参数指定的User对象来调用DAO层实现登录功能
     * @param user
     * @return
     */
    public User userLoginService(User user) {
        return userDao.userLogin(user);
    }
}

<%@ page contentType="text/html;charset=utf-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>实现简单的登录功能</title>
</head>
<body>
<form action="login" method="post">
  用户名:<input type="text" name="userName"/><br/>&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="text" name="password"/><br/>
  <span style="color: red">
      <%= request.getAttribute("error")==null?"":request.getAttribute("error")%>
          </span><br/>
  <input type="submit" value="登录"/>
</form>
</body>
</html>
package com.lagou.demo03.factory;

import com.lagou.demo03.bean.User;
import com.lagou.demo03.dao.UserDao;
import com.lagou.demo03.dao.UserDaoImp;

public class UserDaoFactory {

    /**
     * 通过静态工程方法模式来实现UserDao实现类对象的创建并返回
     * @return
     */
    public static UserDao getUserDao() {
        return new UserDaoImp();
    }
}

package com.lagou.demo03.servlet;

import com.lagou.demo03.bean.User;
import com.lagou.demo03.service.UserService;

import javax.servlet.RequestDispatcher;
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;

@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws 
        ServletException, IOException {
        // 1.获取请求中的用户名和密码信息并打印出来
        String userName = request.getParameter("userName");
        System.out.println("获取到的用户名为:" + userName);
        String password = request.getParameter("password");
        System.out.println("获取到的密码为:" + password);
        // 2.创建UserService类型的对象去实现数据的校验功能
        UserService userService = new UserService();
        User user = userService.userLoginService(new User(userName, password));
        if (null == user) {
            System.out.println("登录失败,用户名或密码错误!");
            request.setAttribute("error", "登录失败,用户名或密码错误!");
            // 实现服务器跳转  共享request和response对象
            RequestDispatcher requestDispatcher = request.getRequestDispatcher("login.jsp");
            requestDispatcher.forward(request, response);
        } else {
            System.out.println("登录成功,欢迎使用!");
            // 将登录成功的用户信息放入session对象中实现多个请求共享
            request.getSession().setAttribute("user", user);
            // 实现客户端跳转
            response.sendRedirect("main.jsp");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws 
        ServletException, IOException {
        this.doPost(request, response);
    }
}

package com.lagou.demo03.test;

import com.lagou.demo03.bean.User;
import com.lagou.demo03.dao.UserDao;
import com.lagou.demo03.dao.UserDaoImp;
import com.lagou.demo03.service.UserService;

public class UserServiceTest {

    public static void main(String[] args) {

        UserDao userDao = new UserDaoImp();
        UserService userService = new UserService();
        User admin = userService.userLoginService(new User("admin", "1234566"));
        System.out.println("找到的数据为:" + admin);
    }
}

package com.lagou.demo03.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DbUtil {
    private static String jdbcName;   // 用于描述驱动信息
    private static String dbUrl;      // 用于描述URL信息
    private static String dbUserName; // 用户描述用户名信息
    private static String dbPassword; // 用户描述密码信息

    // 进行静态成员的初始化操作
    static {
        jdbcName = "com.mysql.jdbc.Driver";
        dbUrl = "jdbc:mysql://localhost:3306/db_web";
        dbUserName = "root";
        dbPassword = "123456";
        try {
            Class.forName(jdbcName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        Connection con = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
        return con;
    }

    /**
     * 关闭连接
     * @param con
     * @throws SQLException
     */
    public static void closeResource(Connection con, PreparedStatement psts) throws SQLException {
        if (null != con) {
            con.close();
        }
        if (null != psts) {
            psts.close();
        }
    }
}

<%@ page import="com.lagou.demo03.bean.User" %><%--
  Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>主页面</title>
</head>
<body>
<h1>登录成功,欢迎<%= ((User)session.getAttribute("user")).getUserName() %>使用!</h1>
</body>
</html>

这个工程,说明了设计模式的重要性,使得程序之间维护的作用
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值