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" %>
现在的时间是:<%= new Date()%>
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" %>
<%!
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程序代码吧!");
}
%>
<%= ia+1 %> <%-- 1 --%>
<%= ib %> <%-- 20 --%>
<%= "我就暂时写到这里吧!"%> <%-- 我就暂时写到这里吧!,这里是jsp注释的方法,底层不识别--%>
注意:在转译时,是不会判断是否错误的,即先全部按照规则变成java,即可以分开写,如
<%! public void f(){
%>
<%!
}
%>
<%
int a=%><%3;%>
<%=
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" %>
id | name | age | salary |
<%= i %> | <%= i %> | <%= i %> | <%= i %> |
源代码循环如下:
输出了多次,即文档内容又多了起来
注释:
格式:
HTML文件的注释,浏览器可以查看到,到java代码里面的out.write方法里面可以看到
<%--… …--%> JSP文件的注释,浏览器看不到,到java代码里面不可以看到
<%//… …%> Java语言中的单行注释,浏览器看不到,到java代码里面可以看到
<%/*… …*/%> Java语言中的多行注释,浏览器看不到注释的内容不会被执行,到java代码里面可以看到
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 这是JSP文件中的注释方式,该方式浏览器是看不到的 --%>
<%
// Java语言中的单行注释 浏览器看不到哦
/* Java语言中的多行注释 浏览器看不到哦! */
%>
指令和动作:
指令格式:
<%@指令 属性=“属性值”%>
指令的属性可以设定多个
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" %>
<%
List
%>
taglib指令:
taglib指令用来扩展JSP程序的标签元素,引入其他功能的标签库文件:
<%@taglib uri="tagLibary" prefix="prefix"%>
include指令:
include指令用于引入另一个JSP程序或HTML文件等,格式如下:
<%@include file="被包含的文件地址"%>
注意:Jsp的转译也是一行一行的,即只要符合就可以识别,且也是从上往下的的放入具体位置
JSP引擎会在JSP文件的转换时期先把file属性设定的文件包含进来,然后开始执行转换及编译的工作
jsp:include/jsp:param:
jsp:include动作用于引入另一个JSP程序或HTML文件等
执行到include时,被include的文件才会被编译
如果include的是jsp文件,那它不会被转换成Servlet文件
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运行时操作,动态的改变--%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
所有页面的公共头部部分就可以写在这里,然后让所有页面包含或引入该文件即可
jsp:forward/jsp:param:
forward动作用于在JSP中实现转发,将请求转发到另一个指定的JSP程序或者Servlet中处理:
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 设置属性,即给请求信息添加属性,保存在request里面--%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
服务器转发后执行这里的代码哦!
<%= "获取到的数值为:" + request.getParameter("name")%>
<%--实际上由于有两个class,即两个servlet,即转发时
可以得到request的值,由于共享,即扩展,所以也可以得到对应name的值 --%>
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" %>
<%
out.println("
");
out.println("Hello World!");
out.println("");
//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);
%>
request内置对象:
request对象封装的是调用JSP页面的请求信息,它是HttpServletRequest接口的一个实例
该对象的属性值只在一个请求中保存
常用方法如下:
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String serverName = request.getServerName();
System.out.println("获取到的服务器名称为:" + serverName);
int serverPort = request.getServerPort();
System.out.println("获取到的服务器端口号为:" + serverPort);
// 通过内置对象设置属性信息,也就是存储数据
request.setAttribute("name", "guanyu");
%>
<%-- 实现转发效果,也就是服务器跳转 --%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%= "获取到的属性值为:" + request.getAttribute("name")%> <%-- guanyu --%>
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" %>
<%
// 表示每隔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 %>
session内置对象:
session对象表示浏览器和服务器之间的一次会话,一次会话可以包含多次请求
在多次请求之间可以借助session对象存储信息,它是HttpSession类型的一个实例
该对象的属性值在一次会话范围中保存,保存在服务器端,只要不关闭服务器,默认半个小时内都可以访问,即30分钟
常用方法如下:
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
session.setAttribute("name", "liubei");
System.out.println("session内置对象中的数据设置成功!");
%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%= "获取到的属性值为:" + session.getAttribute("name")%>
application内置对象:
application对象是一个web程序的全局变量,它是ServletContext类型的一个实例
在整个服务器上保存数据,所有用户共享
常用方法如下:
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
application.setAttribute("name", "zhaoyun");
System.out.println("application内置对象中的数据设置成功!");
%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%= "获取到的application内置对象的属性为:" + application.getAttribute("name")%> <%-- zhaoyun --%>
pageContext内置对象:
pageContext对象是PageContext类型的对象,可以使用这个对象来管理其他的隐含对象
只在一个页面中保存数据,即其他的请求就没有了
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
pageContext.setAttribute("name", "huangzhong");
System.out.println("pageContext内置对象中的数据设置成功!");
%>
<%= "获取到的pageContext内置对象中的属性值为:" + pageContext.getAttribute("name")%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%= "获取到的pageContext内置对象中的属性值为:" + pageContext.getAttribute("name")%> <%-- null --%>
exception内置对象:
exception 对象是Throwable的实例,表示的是JSP的异常信息
如果要使用它,必须将对应页面page指令的isErrorPage属性设置成true
单个页面的处理方式
<%@page errorPage="error.jsp" %>
在web.xml中配置统一的异常处理页面:
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">
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="error.jsp" %><%--指定异常的页面,当发生错误时
将这个页面信息给文档,而不是将原来默认的信息给文档
若和配置文件一起,则因为就近原则,使用这个文件,导致不读取配置文件了,否则读取配置文件
--%>
<%
int ia = 10;
int ib = 0;
System.out.println(ia / ib); // 算术异常
%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
int[] arr = new int[5];
System.out.println(arr[5]); // 数组下标越界异常
%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isErrorPage="true" %> <%--将这个页面设置为错误页面,别人发生错误时
<%@ page errorPage="error.jsp" %>使用这个指向
则会使用这个页面
若没有设置true,则下面的exception就会报错,不可使用
--%>
<%
if (exception != null) {
out.println("异常的错误信息为:" + exception.getMessage()); //异常信息
}
%>
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" %>
<%-- 表示创建Student类型的对象由student引用变量负责记录 有效范围是当前页面
相当于给你创建对象,不用自己创建对象了,即Student student = new Student();
所以Student这个变量就使用了,即不可再用Student这个变量了,否则报错
--%>
<%-- 表示将student对象中名字为id的属性值设置为1002
--%>
<%-- 表示将student对象中名字为name的属性值设置为guanyu--%>
<%--
注意:id和name是student引用的属性值,即成员变量的名字,不可忽略大小写
使用上面相当于调用对应的setxxx,xxx是他们对应成员变量的首字母忽略大小写的名字
如setId,setid等等,setName,setname等等,实际上是成员变量对应set的首字母大小写忽略
--%>
<%
// 创建Student类型的对象并设置成员变量的数值
//Student student = new Student(); 上面若创建对象,则这个名字不可使用
//student.setId(1001);
//student.setName("zhangfei");
%>
<%--<%= "获取到的学号是:" + student.getId() %> <%– 1001 1002 –%>
<%= "获取到的姓名是:" + student.getName() %> <%– zhangfei guanyu –%>--%>
<%-- 表示获得student对象中名字为id的属性值
--%>
学号是:
<%-- 表示获得student对象中名字为name的属性值
--%>
姓名是:
<%--其中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,不会报错
--%>
使用方式:
使用jsp:useBean的方式创建javaBean实例:
保存范围有:page|request|sessin|application,默认为page范围
使用jsp:setProperty的方式设置javaBean的属性值:
<%--注意:value和param不能一起,否则报错--%>
使用jsp:getProperty的方式获取javaBean的属性值:
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--
注意:param需要其他请求信息的数据,即其他页面传过来的参数,且不 能和value一起,否则报错
因为他们都是对数据进行操作的,底层只能操作一个,若有多个,则会报错的
且要注意空格要写,你写是去,会提示你的,若执意运行,则报错
--%>
<%--
Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 获取名字为student对象中属性为id的数值并打印 --%>
经过参数赋值后获取到的学号是:
经过参数赋值后获取到的姓名是:
<%--
对于jsp:useBean的底层,他是会先去调用对应的getAttribute("student"))方法,来获得Student对象
若没有,则创建该类型对象,然后设置进去,由于是地址,那么若有setProperty,则会设置值给这个对象
所以若需要里面的东西,就要取出来,则必须还要使用jsp:useBean方式
使得调用对应的getAttribute("student"))方法取出来
--%>
上面取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" %>
<%
// 表示从session对象中删除名字为student的属性
session.removeAttribute("student");
%>
<%= "删除数据成功!" %>
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" %>
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" %>
登录成功,欢迎<%= ((User)session.getAttribute("user")).getUserName() %>使用!
这个工程,说明了设计模式的重要性,使得程序之间维护的作用