第一章 前言
1.1 JAVA的版本
JAVA版本 | 级别 | 适合开发 |
---|---|---|
JAVASE(J2SE) | 桌面级别 | 桌面开发 |
JAVAEE(J2EE) | 企业级别 | 企业开发 |
JAVAME(J2ME) | 微小版本 | 手机开发 |
1.2 软件的架构
目前主流的软件架构模式两种:C/S架构,B/S架构
架构 | 特点 | 优缺点 |
---|---|---|
C/S(client server)客户端服务器架构 | 必须本地下载特点的软件,像QQ,微信,迅雷 | 1.图形界面3d效果比较好 2.服务器功能一旦升级,强制要求客户端系统更新 |
B/S(browser server)浏览器 服务器架构 | 无需下载客户端,只要有浏览器可直接访问 | 1.服务器功能升级,直接可以升级服务器端 2.图形效果,3d特效不适合,通过HTTP协议访问 |
1.3 浏览器服务架构图
1.4 服务器
1.4.1 什么是web?
万维网,网站。一般网站提供给客户资源:
静态资源:静态网页,不存在数据传输。如HTML,CSS,JS,数据不是动态获取。
动态资源:动态提取数据。JAVAEE中两个核心组件:Servlet,JSP。
1.4.2 什么是web服务器?
web服务器可以使得开发的web应用实现运行和发布,只有部署到服务器下的项目,可以实现从客户端获取到,客户端通过浏览器,基于HTTP协议实现访问。
web服务器为多个客户端提供服务。
1.4.3 常见的服务器
开源的:(开放源码,免费)
Tomcat:主流服务器(简单,适合初学者) jetty:淘宝,运行效率高一点 resin:新浪,开源服务器中,性能比较好的
收费的:(服务以及支持的功能强大,软件大,耗能大)
webLogic:Oracle
webSphere:IBM
Tomcat服务器:
免费开源项目,Apache软件基金会的akarta项目。目前最新10版本。
解压版(8.5版本),安装版
注意:
1,不要解压到层级结构深的文件夹
2,不要解压到中文目录下
Tomcat文件目录结构:
文件目录 | 内容 |
---|---|
bin | 存放可以直接执行的二进制文件,启动服务器,关闭服务器的指令文件 |
conf | 配置文件夹,有重要的配置文件, server.xml 用来配置服务器的,服务器端口,编码。 web.xml用来做项目部署的配置 |
lib | tomcat类库,存放Tomcat运行时所需jar包 |
logs | 用来存放日志文件,记录tomcat的启动,关闭,访问,tomcat错误信息 |
temp | tomcat的临时文件,这个目录在tomcat停止后删除掉 |
webapps | 用来存放web应用,每个文件夹对应一个项目,项目部署到此文件夹 |
work | 运行资源的时候,生成的文件,如:运行JSP时,生成的java和class文件 |
1.4.4 web项目
web项目结构:
文件目录 | 内容 |
---|---|
javaweb01 | web应用名字 |
src | java源代码 |
web | 客户端资源 |
WEB-INF | web.xml:项目全局配置文件 lib 文件夹;存储jar包,如:数据库驱动文件 classes:存储后端编译文件(反射) |
index.jsp | 应用系统的首页面,默认情况访问的是页面 |
配置服务器:
Edit Configurations:
项目输出配置:
1.4.5 关于服务器的访问:
基于HTTP协议,请求(request)响应(response)模型
HTTP请求URL格式:
url : 协议名://ip地址:端口号/项目名/页面名.html?key=value&key=value#锚
例如:localhost:8080/hello.html这里的localhost : 本地ip地址,可以使用127.0.0.1
8080 是tomcat的默认端口,可以更改,建议四位,80以上,防止被占用
request:请求
GET:明文的请求方式POST:密文的请求方式
response:响应
200:响应成功
404:客户端问题,检查请求路径问题存在,服务器是否启动
500:服务器内部出错
第二章Servlet
2.1 Servlet的基本概念
JAVAEE中最核心的组件,Server Applet,服务器端的代码和功能,主要是完成客户端的接收,处理以及响应,基于请求 - 响应模型的组件
2.2 Servlet 作用
1.接收客户端发来的请求(注册,网页填写注册信息)
2.处理请求(增加到数据库当中)
3.响应(反馈给客户端)
2.3 Servlet 创建
创建servlet
//Servlet的访问路径
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("发出了get请求");
System.out.println(request.getParameter("username"));
}
}
通过客户端访问:
url: localhost:8080/MyServlet?username=yushuang
<body>
欢迎学习javaee!!!这是idea 的项目配置,哈哈哈
<form action="MyServlet">
username: <input type="text" name="username">
<input type="submit">
</form>
</body>
总结:
Servlet是一个类,是一个继承了HttpServlet 抽象父类的子类。
2.4 Servlet的配置
1.注解(web3.0版本,推荐使用)
@WebServlet("/MyServlet") //注解添加在Servlet的上方,省略value=
@WebServlet(value = "/MyServlet") //访问路径
注意:
1, url不可以重复的
2, url是客户端访问路径
3,Servlet可以设置多个路径
2.配置文件法web.xml中添加手动配置
<!-- 为servlet手动添加配置-->
<!--servlet类路径-->
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.qf.web.MyServlet</servlet-class>
</servlet>
<!--客户端访问路径-->
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/My</url-pattern>
</servlet-mapping>
注意:
配置文件和注解可以同时使用,url不能重复
2.5 Servlet的访问方式
4种方式:
1.通过URL直接访问
2.通过超级链接访问Servlet
3.通过from表单访问(同步请求)
4.通过脚本访问
location.href = " ";
AJAX(重点,异步请求)
2.5.1 通过URL方式访问
程序员做测试使用,默认发送的GET请求。
后端在接收请求的时候,需要使用doGet()处理请求
http://localhost:8080/MyServlet?username=yushuang&pass=123456
2.5.2 通过超级链接方式访问
默认发送的是GET请求。
<a href="MyServlet?username=yushuang&pass=123456">
点击试试
</a>
2.5.3 通过表单方式访问
默认发送的是GET请求,但是可以通过method属性修改请求方式。
同步请求:
<form action="MyServlet" method="GET/POST">
....
<input type="submit">
</form>
2.5.4 通过脚本方式访问
1,同步请求,通过按钮触发事件,页面跳转的方式,跳转后台
<body>
<button>
点击试试
</button>
</body>
<script src="js/jquery-3.6.0.js"></script>
<script>
$('button').click(function () {
location.href = "FormServlet?username=ys&pass=555";
});
</script>
2,异步请求,通过ajax方式发出请求,设置请求类型:GET/POST
// getJSON() get() post() ajax()
//异步 不会发生页面跳转
$(':button').click(function () {
// $.get('FormServlet',{username:$('#username').val(),pass:$('#pass').val()},function () {
// //响应的时候
// })
$.ajax({
"url":"FormServlet",
"data":{username:$('#username').val(),pass:$('#pass').val()},
"type":"get"
})
})
2.6 Servlet的体系结构和生命周期
2.6.1Servlet的"家谱"
自定义的Servlet是一个类,继承抽象父类: HttpServlet
Servlet中的方法:
方法名 | 含义 | 参数 |
---|---|---|
init() | Servlet初始化方法,初始化Servlet时会被tomcat容器自动调用 | 有带参数 |
service() | Servlet提供服务调用的方法,在每次被请求的时自动调用,判断请求的类型 | request response |
destory() | Servlet被销毁的时候,容器自动调用,需要清理垃圾,覆盖该方法 | 无参数 |
doGet() | 处理get请求,自动调用 | request response |
doPost() | 处理post请求,自动调用 | request response |
2.6.2Servlet的生命周期
从第一次请求Servlet > 容器创建对象(调用构造方法:1次) > 容器自动初始化 (调用init() 方法 1次) >调用服务方法 (service() n次)
service()方法请求类型GET POST DELETE > doGet() (n次) / doPost() (n次) > 容器关闭 (调用destroy() 1次 ,销毁Servlet对象)
代码:
package com.qf.web;
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("/LifeServlet")
public class LifeServlet extends HttpServlet {
public LifeServlet(){
System.out.println("servlet被创建了");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//判断
System.out.println("service提供服务");
if(req.getMethod().equals("GET")){
doGet(req,resp);
}else{
doPost(req,resp);
}
}
@Override
public void destroy() {
System.out.println("销毁了servlet");
}
@Override
public void init() throws ServletException {
System.out.println("初始化了servlet");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理了post");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理了get");
}
}
生命周期:
2.6.3 Servlet的特点总结
特点:单实例,多线程。
Tomcat为所有客户端对于同一个Servlet只创建一个对象(单例),每个客户端tomcat提供一个线程,因此多个客户端访问的时候,多线程。
当操作共享资源? 线程安全?如何保证线程安全?
三种方式:
- 加线程锁 synchronized
- 实现接口 : SingleThreadModel (高版本不推荐)
- 避免使用共享变量,尽量使用局部变量
2.6.4 反射机制
JAVA运行机制:编辑 解释
使用反射:
反射的基本概念:
通过操作字节码文件,反向获得该字节码文件所对应的源文件中有哪些属性,方法还有构造方法,此过程为反射。
操作反射的API:
java.lang.Object 所有类对象对应的根类 Object
java.lang.Class 所有字节码文件对象对应的根类 Class
java.lang.reflect.*; 所有反射出来的对象类型
如何获得运行时类对象(反射对象所对应的类对象; 获得反射对象)
1. Class c = 对象.getClass();
2. Class c = 类名.class;
3. Class.forName("字节码完整路径");//推荐
API:
类型 | 含义 | 所在包 |
---|---|---|
Class | 操作反射对象的类型 | java.lang |
Method | 反射对象中方法的类型 | java.lang.reflect |
Constructor | 反射对象中构造的类型 | java.lang.reflect |
Field | 反射对象中属性的类型 | java.lang.reflect |
获取反射对象代码:
package com.qf.web.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestClass {
public static void main(String[] args) {
//如何获取?
// 1 Student类必须存在
// Student s1 = new Student();
// Class c1 = s1.getClass();
// 2 指定性强
//Class c1 = Student.class;
// 3 传参数灵活 有异常
Class c1 = null;
try {
c1 = Class.forName("com.qf.web.test.Student");
}catch (Exception e){
}
// c1对象 反向获取当前操作的类的属性 方法 构造
//获取到所有属性
Field [] f = c1.getFields();
for (Field ff:f
) {
// System.out.println(ff.getName());
}
//获取方法(带继承的)
//Method[] m = c1.getMethods();
//不带继承的
Method[] m = c1.getDeclaredMethods();
for (Method mm:m
) {
// System.out.println(mm.getName());
}
// 获取构造方法
Constructor[] cs = c1.getConstructors();
for (Constructor css:cs
) {
System.out.println(css);
}
}
}
动态创建对象和调用方法:
方法 | 含义 | |
---|---|---|
newInstance() | 反向创建对象实例,Class中定义的方法 | 默认调用的空构造 |
invoke() | 反向调用方法,Method中定义的 |
动态代理实现:
public class TestInstance {
public static void main(String[] args) {
Class c1 = null;
try {
c1 = Class.forName("com.qf.web.test.Student");
//反向创建Student对象
Object o = c1.newInstance();
//反向调用方法
Method method = c1.getMethod("study",String.class);
//动态执行方法
Object res = method.invoke(o,"jack");
System.out.println(res);
}catch (Exception e){
}
}
}
第三章 Servlet请求获得和请求处理
3.1 请求获得
Tomcat在获得客户端请求后,动态执行doGet() ,doPost(),自动传入两个参数。其中的request是代表请求对象。
request的类型: HttpServletRequest
方法 | 含义 | 参数/返回值 |
---|---|---|
getParameter(”key/name“) | 获取客户端发来的数据 | key 键值对key值 name表单的属性 String 获得对应的值 |
getParameterValues(”复选框name“) | 获取客户端复选框的值 | String[] |
getMethod() | 获得请求的类型 | String : GET POST… |
getRemoteAddr() | 获得远程IP | |
getRealPath() | 获得真实路径 | |
setCharacterEncoding(“utf-8”) | 中文处理 |
请求发送代码:
<form action="RegisterServlet" method="post">
username: <input type="text" name="username">
<br>
pass: <input type="password" name="password">
<br>
gender:
<input type="radio" name="g" value="boy" checked> boy
<input type="radio" name="g" value="girl"> girl
<br>
city:
<select name="city" id="">
<option value="DL">大连</option>
<option value="BX">本溪</option>
<option value="BJ">北京</option>
</select>
<br>
Hobbies:
<input type="checkbox" name="hobby" value="sing"> 唱歌
<input type="checkbox" name="hobby" value="dance"> 跳舞
<input type="checkbox" name="hobby" value="ball"> 篮球
<input type="submit">
</form>
请求获得代码:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//中文处理 post
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String g = req.getParameter("g");
String city = req.getParameter("city");
System.out.println(username + "," + password + "," + g + "," + city);
String[] hos = req.getParameterValues("hobby");
System.out.println("爱好如下:");
for (String s: hos
) {
System.out.println(s);
}
//不会直接操作数据库数据,代码耦合度高
}
注意:
请求发送和获取的key值(name值)一定要对应。
3.2 请求处理
请求的处理使用架构模式 : MVC架构。
3.2.1 什么是MVC?
MVC 是一种模式,将代码实现分层:
MVC: M-Model V-View C-Controller
模型-视图-控制器
模型: 数据模型,数据实体,实体类 (JAVA类)
视图: 页面 (HTML ,JSP )
控制器: 和页面交互,实现请求和响应的 (Servlet)
3.2.2 MVC的好处?
1, 解耦,分层思想,代码职责解耦
2, 项目层次清晰
3, 更加利于代码的维护
3.2.3 MVC的三层架构?
层 | 命名 | 负责 | 操作 |
---|---|---|---|
控制层 | controller / action | 调取业务层数据,完成和客户端视图的请求和响应交互 | Servlet |
业务层 | service / biz / business | 调取数据层数据,完成粗粒度的业务,注册,登录,加购物车,一个业务需要调用多次Dao | class |
数据层 | dao | 和数据库衔接,完成细粒度的操作,一个方法只做一件事(增,删,改,查) | class |
试图层 | web里资源 | 发请求的 | html jsp |
注意:
数据模型和表对应:
date Dateint/double int/double
varchar String
3.3 响应请求
3.3.1 response做响应流
这种方式适合响应信息内容少,更多的是用在AJAX异步请求时。
//获取响应流
PrintWriter pw = response.getWriter();
//响应流反馈(在JAVA写前端)
pw.print("<script>alert('');</script>");
3.3.2 响应时跳转
Servlet负责做业务操作,获取结果; JSP负责结果的显示。
请求 > Servlet > JSP。
两种跳转方式:
1,请求转发
request对象,HttpServletRequest类型
特点:
A资源向B资源发出请求,B资源并没有响应,B资源将请求向下传递给C资源,C资源做响应,A请求结束。
特点:
1.请求对象只有一个,只有一个请求,传递下去
2.所有的资源都需要在同一个服务器下
3.请求的URL不发生改变
实现步骤Servlet转发:
//请求数据存储 参数1 key ,参数2 value
request.setAttribute("list",list);
//请求分发,跳转到depts.jsp页面,请求和响应传递下去
request.getRequestDispatcher("depts.jsp").forward(request,response);
JSP负责响应:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="bootstrap.css">
</head>
<body>
<%
//获取集合
ArrayList<Dept> list = (ArrayList<Dept>)request.getAttribute("list");
%>
<div class="container">
<h2 class="page-header">部门信息</h2>
<table class="table table-striped">
<tr>
<td>部门编号</td>
<td>部门名称</td>
<td>部门位置</td>
<td>操作</td>
</tr>
<%
for (int i = 0; i < list.size(); i++) {
%>
<tr>
<td><%=list.get(i).getDeptno()%></td>
<td><%=list.get(i).getDname()%></td>
<td><%=list.get(i).getLoc()%></td>
<td>
<a href="">删除部门</a>
<a href="">修改部门</a>
</td>
</tr>
<%
}
%>
</table>
</div>
</body>
</html>
2,响应重定向
response对象,HttpServletResponse类型
特点:
A资源向B资源发出请求,B资源并没有响应,B资源告知A资源向别人发出请求,A资源重新发出新请求给C资源,C资源做出响应。
特点:
1.请求对象有多个
2.所有的资源不一定在同一个服务器
3.请求的URL肯定发生改变
实现步骤:
response.sendRedirect("error.jsp");
响应的时候中文乱码:
response.setContentType("text/html;charset=UTF-8");
总结:
同步请求(页面跳转)
请求转发:A>B B>C
响应重定向:A>B A>C
异步请求
AJAX异步:A>B B>A
3.4 Servlet状态管理(重点)
3.4.1 状态跟踪的原因?
HTTP协议是无状态协议,只要是请求发生了变化,之前的请求的数据就失效找不到。因此需要状态跟踪。
3.4.2 四个作用范围
范围 | 类型 | 对应对象 |
---|---|---|
页面范围 | PageContext | pageContext |
请求范围 | HttpServletRequest | request |
会话范围(缓存技术) | HttpSession | session |
上下文范围 | ServletContext | application |
范围: 请求范围 < 会话范围 < 上下文
注意:
一个请求范围包含多个页面,如登录请求 : login.jsp -> main.jsp
一个会话范围包含多个请求,如需要登录后(登录请求),显示部门模块(部门请求),两个请求实现共享数据(数据缓存)
会话: 一个客户端和服务器之间的一个连接
一个上下文范围包含多个会话,客户端A和客户端B两个会话共享数据()
3.4.3 数据存取
方法 | 含义 | EL简化写法 |
---|---|---|
状态对象.setAttribute(key,value) | 对象设置数据到范围上 | |
状态对象.getAttribute(key) | 对象设置数据到范围上 | ${key} |
3.4.4 请求范围的实现
servlet:
//存储数据
request.setAttribute("username",username);
request.getRequestDispatcher("main.jsp").forward(request,response);
jsp:
您好 <span>
<%-- <%=request.getAttribute("username")%>--%>
${username}
</span>
注意:
请求范围仅限于操作一个请求对象上的数据传输,一旦请求发送改变,数据资源丢失。
3.4.5 数据缓存技术
数据缓存又叫做数据追踪技术,将数据缓存起来,需要的时候提取。
缓存的方式:
① 纯客户端缓存(HTML5,JS了解)
localStorage 硬盘级缓存: 在客户端直接存储到浏览器上,不清除不失效
sessionStorage 会话级缓存: 在客户端存储到浏览器的会话,浏览器不关闭不失效
//实现
sessionStorage.setItem(key,value);//存
sessionStorage.getItem(key) //取
② 服务器端缓存(重点)
cookie : 服务器根据请求的需要,将数据缓存到浏览器上(缓存到浏览器上)
session : 服务器根据请求的需要,将数据缓存到服务器上 (缓存到服务器上)
cookie:
cookies,保存在客户端的小文本文件,将一些数据缓存到了用户的本地。
cookie的工作原理:
cookie实现步骤:
1.服务器接收请求,有缓存需要,响应的时候创建缓存
//1. 创建缓存对象
Cookie c = new Cookie(key,value);//key value必须是字符串
//如
Cookie c1 = new Cookie("username",username);
//2.设置缓存时间
c1.setMaxAge(Integer.parseInt(coo) * 60);//秒为单位 -1默认值 没有缓存
//3.通过响应对象传输给客户端
response.addCookie(c1);
2.客户端通过缓存登录
<%
//获取缓存数据
Cookie[] c = request.getCookies();
//遍历
for (int i = 0; i < c.length; i++) {
//判断是否缓存用户名密码
if(c[i].getName().equals("username")){
//存储
request.setAttribute("username",c[i].getValue());
//直接到首页,不做登录
request.getRequestDispatcher("main.jsp").forward(request,response);
}
}
%>
session:
session叫做会话对象,会话对象用来记录数据信息对象,会话指的是某个客户端和服务器之间建立的一次连接,称之为一个会话(浏览器的窗口),整个会话中,客户端可以向服务器不断的发送请求。
session的工作原理:
session的实现步骤:
1.Servlet中创建session对象,存数据
HttpSession session = request.getSession();
session.setAttribute("username",username);
2.但凡需要数据,JSP取数据
// session.getAttribute("username");
${username}
3.session的失效
自动失效:(没有关闭浏览器,没有注销登录)
1- 默认时长
30分钟,tomcat服务器为Session 提供30分钟的有效缓存时间。
2- 修改默认时间
<session-config>
<session-timeout>60</session-timeout>
</session-config>
手动失效:
1- 手动关闭浏览器 session生命周期: 以建立服务器和客户端会话为开始 , 以关闭浏览器为会话结束
2- 不关闭浏览器,手动失效,登出,退出,注销
HttpSession session = request.getSession();
//让session失效
session.invalidate();
cookie和session的区别(重点)
session(会话) | cookie | |
---|---|---|
含义 | 缓存到服务器端 | 缓存到本地客户端 |
内容 | 可以缓存字符串,对象,集合… | 缓存字符串小文本 |
安全性 | 安全性高,无限制 | 安全性差,有限制 |
服务器压力 | 及时失效,销毁,占用服务器空间,负载压力大 | 每个客户端上缓存清除,减轻服务器压力 |
3.4.6 上下文(了解)
整个项目的全局对象,涉及n个客户端的n个会话。每个tomcat下的项目只对应一个上下文对象。
上下文对象的创建:服务器启动,项目部署,容器为项目创建一个上下文对象,作为数据共享区域。
上下文对象的销毁:服务器关闭
上下文对象的实现步骤:
(功能: 每个用户访问主页,显示: xxx登陆者)
Servlet存:
//获得上下文对象
ServletContext context = request.getServletContext();
//先取出次数
if(context.getAttribute("count") == null){
//第一个访问者
context.setAttribute("count","1");
}else{
String count = context.getAttribute("count").toString();
int c = Integer.parseInt(count);
context.setAttribute("count",++c);
}
JSP 页面获取:
//El表达式获取
您是${count}位访问者
3.5 Servlet其他配置
第四章 过滤器Filter
第五章JSP
5.1 什么是JSP?
JSP : java server pages,java服务端页面,本质是Java类(JSP就是Servlet),看起来是页面。是JAVAEE帮助我们将Servlet转化成页面。
Servlet : 在服务器端,负责请求处理,JAVA
JSP: 在客户端,负责显示结果,本质是JAVA,看起来是视图
5.2 JSP的构成?
1.指令语言
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
2.客户端语言
HTML CSS JS ....
3.JAVA语言
<%
%>
4.表达式语言
<%= JAVA内容 %>
5. 注释
<!-- --> 客户端注释
/* */ JAVA CSS
// JAVA
<%-- --> JSP 注释
5.3 作用:
帮助Servlet实现显示的部分,简化Servlet响应的过程。
5.4 EL和JSTL
5.4.1 EL表达式
EL: 表达式语言 ,简化了JSP写法。没有影响执行效率。简化的是 <%= %>
语法规则:
${表达式}
${对象.属性/参数}
EL中对象(6个对象)
5.4.2 JSTL 标签库
JSP中提供第三方插件库,提供对应JAVA代码生成的标签。
作用: 与EL表达式结合,快速生成后端代码。
使用步骤:
1,引入jar包(标签库驱动包),粘贴到lib,
2,JSP页面中引入第三方库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
taglib 标签库指令 prefix 库前缀 uri 路径
3,使用JSTL中提供的标签
<c:xx>
</c:xx>
示例:
<c:if test="5 > 3">
嗯,哈哈
</c:if>
//test条件
替换:
<%
if(5 > 3){
%>
嗯哈哈
<%
}
%>
查询简化:
<c:forEach items="${l}" var="e">
<tr>
<td>${e.empno}</td>
<td>${e.ename}</td>
<td>${e.hiredate}</td>
<td>${e.sal}</td>
<td>
<a onclick="del(${e.empno})" href="#">删除</a>
<a href="">修改</a>
</td>
</tr>
</c:forEach>
items 迭代集合 var 迭代变量
注意:
var items 连用, 相当于forEach循环
begin end step 连用 相当于循环结构
<c:forEach begin="1" end="10" step="1" varStatus="a">
${a.index} 于老师真好看!!<br>
</c:forEach>
<c:forEach items="${l}" var="e">
<tr>
<td>${e.empno}</td>
<td>${e.ename}</td>
<td>${e.hiredate}</td>
<td>${e.sal}</td>
<td>
<a onclick="del(${e.empno})" href="#">删除</a>
<a href="">修改</a>
</td>
</tr>
</c:forEach>
<%-- l 是后端发来的集合key值 --%>
5.5 分页
分页查询: 将数据实现按照页码分开查。
1,真分页 (数据层开始实现分页,根据需要查询)
2,假分页 (数据层获取还是所有数据,但是客户端实现分页插件)
分页需要元素:
1, 第几页
2, 总共多少条数据
3, 一页显示几个
4, 总共几页
5, 起始位置
数据层:
-- 查询第一页数据
select *
from emp
limit 起始位置,查询个数
-- 查询第二页数据
-- 计算起始位置??
分页器:
package com.qf.web.common;
/**
* 分页器
*/
public class Pager {
private int counts; //总记录数
private int page ; //一页几条数据
private int currPage; // 当前第几页
private int pages;// 总共几页
private int start; //起始位置
public Pager(){
}
public Pager(int page, int currPage) {
this.page = page;
this.currPage = currPage;
// 3 3
//计算出来,起始位置
start = page * (currPage - 1 );
}
public int getCounts() {
return counts;
}
/**
* 必须先设置总共几页才能查询
* @param counts
*/
public void setCounts(int counts) {
//总记录
this.counts = counts;
//计算页数
this.pages = counts % page == 0 ? counts / page : counts / page + 1;
}
// ...
}
DAO :
public ArrayList<Emp> queryAll(Pager pager) {
Connection conn = DBUtil.getConn();
ArrayList<Emp> list = new ArrayList<Emp>();
PreparedStatement preparedStatement = null;
try {
preparedStatement = conn.prepareStatement("select * from emp limit ?,?");
preparedStatement.setInt(1,pager.getStart());
preparedStatement.setInt(2,pager.getPage());
ResultSet rs = preparedStatement.executeQuery();
while(rs.next()){
Emp emp = new Emp(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getInt(4),
rs.getDate(5),rs.getDouble(6),rs.getDouble(7),rs.getInt(8));
list.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
public int counts() {
Connection conn = DBUtil.getConn();
int c = 0;
PreparedStatement preparedStatement = null;
try {
preparedStatement = conn.prepareStatement("select count(*) from emp");
ResultSet rs = preparedStatement.executeQuery();
if(rs.next()){
c = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return c;
}
Service:
@Override
public ArrayList<Emp> queryAll(Pager pager) {
// 1. 查询总数
pager.setCounts(dao.counts());
//2 查询内容
return dao.queryAll(pager);
}
5.6 九大内置对象
JSP可以获取到Servlet存储的数据?
JSP的本质是Servlet,JSP就是和Servlet一样的JAVA类,每次创建JSP的时候,tomcat给自动给JSP提供9个内置对象。
内置对象 | 类型 | 含义 |
---|---|---|
pageContext | PageContext | 页面对象 |
request | HttpServletRequest | 请求对象 |
session | HttpSession | 会话对象 |
application | ServletContext | 上下文对象 |
response | HttpServletResponse | 响应对象 |
out | JspWriter | 输出对象 |
config | ServletConfig | 配置对象 |
page | Object | 页面对象 |
exception | Throwable | 异常对象 |
注意:
获得请求范围上的数据,可以使用 ${ }简写。
如:
<%= application.getAtrribute("count"); %>
${count}
第六章 AJAX异步请求
6.1客户端发送AJAX请求
通过jQuery发送AJAX请求:
$.getJSON();
$.get()
$.post()
$.ajax()
6.2 服务器端响应请求
//response
//获取响应流
PrintWriter pw = response.getWriter();
//响应文本
pw.print(文本);
1.响应验证码
<script src="jquery.js"></script>
<script>
$('#get').click(function () {
$.get("../CodeServlet",function (r) {
$("#get").val(r)
})
})
</script>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//生成一个验证码(四位大写 65-90)
char [] c = new char[4];
String code = "";
for (int i = 0; i < c.length; i++) {
c[i] = (char) ((90 - 65 + 1 ) * Math.random() + 65);
code += c[i];
}
System.out.println(code);
//响应给前端
response.getWriter().print(code);
}
2.员工编号异步校验
<script>
$(':text:first').blur(function () {
$.get("CheckEmpServlet",{empno: $(':text:first').val()},function (r) {
if(r == "0"){
alert("员工编号可用");
}else{
alert("员工编号已占用");
}
})
})
</script>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取员工编号
int empno = Integer.parseInt(request.getParameter("empno"));
EmpService service = new EmpServiceImpl();
Emp emp = service.queryByNo(empno);
if(emp == null){
//没有
response.getWriter().print("0");
}else{
response.getWriter().print("1");
}
}
解析JSON的jar 包:
//response
//获取响应流
PrintWriter pw = response.getWriter();
//响应JSON
pw.print(JSON对象);
pw.print(JSON数组);
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得数据(第几页)
int curr = Integer.parseInt(request.getParameter("curr"));
//分页器
Pager p = new Pager(3,curr);
//调用业务层
EmpService empService = new EmpServiceImpl();
ArrayList<Emp> list = empService.queryAll(p);
//直接响应 A> B B > A
//AJAX JSON数组
//借助插件 gson : 后端集合/对象 转化为前端的 JSON
Gson gson = new Gson();
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print(gson.toJson(list));
}