jsp
1. JSP的概述
1.1 什么是JSP
JSP:Java Server Pages (Java服务器端页面),其实就在HTML中嵌入Java代码。
JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。可以跨平台,在不同操作系统下运行。
1.2 JSP的优势
SUN公司提供了动态网页开发技术:Servlet。Servlet自身有一些缺点,SUN公司发现了这些问题,推出了一个新的动态网页开发技术JSP。
Servlet的缺点:
- Servlet需要进行配置,不方便维护
- Servlet很难向网页中输出HTML页面内容
2. JSP的运行原理
2.1 创建一个JSP页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>hello jsp。。。</h1>
</body>
</html>
2.2 JSP的运行原理
JSP文件翻译成Java文件,将这个Java文件编译生成class文件,最后运行class文件
3. JSP的脚本元素
3.1 什么是JSP的脚本元素
JSP = HTML + Java代码 + JSP自身东西
JSP的脚本元素就是在JSP中嵌入Java代码
3.2 JSP的脚本元素的分类
3.2.1 声明标签
语法:<%! 变量或方法声明 %>
写在这个脚本中的代码,翻译成Servlet内部的成员变量或成员方法。
用法:
<%!
//声明变量
int i=3;
%>
这个要标签要慎用!!
3.2.2 表达式标签
语法: <%= 表达式 %>
写在这个脚本中的代码,翻译成方法内部的out.print();当中的内容。
用法:
<%=i
//输出变量或者表达式
%>
3.2.3 程序代码标签
语法:<% 程序代码 %>
写在这个脚本中的代码,翻译成方法内部的局部变量或方法内部代码片段。
用法:
<%
//程序代码
int x=5;
int y=5;
%>
<%= x+y*y %>
4. JSP的开发模式之MVC模式
动态网页开发模式的发展:
5. 开发中的路径问题
5.1 路径问题描述
提供一些页面,在页面中会提供链接或者表单,当点击链接或者表单的时候需要进行提交,提交到Servlet中。从页面向Servlet发送请求的地址(路径)应该如何编写。
5.2 路径的分类
5.2.1 相对路径
相对路径的写法:相对路径不是以 / 开头的。
相对路径的使用:在跟路径下的页面访问Servlet
demo.jsp的访问路径:
http://localhost:8080/web02/demo.jsp
Servletdemo1的访问路径:
http://localhost:8080/web02/Servletdemo1
对与demo:这两种方式均可
<a href="Servletdemo1">访问Servletdemo1</a></br>
<a href="./Servletdemo1">访问Servletdemo1</a>
对于demo0:
<a href="../Servletdemo1">访问Servletdemo1</a>
5.2.2 绝对路径
绝对路径的写法:通常以 / 开始的路径
使用绝对路径,不需要关心当前文件和要请求的文件的相对位置的关系!!!
注意:
- 绝对路径分成服务器端路径和客户端路径
- 客户端路径 需要带工程名
- 服务器端路径 不需要带工程名(后面会提到)
对与demo和demo0:
<a href="http://localhost:8080/web02/Servletdemo1">访问Servletdemo1</a></br>
<a href="/web02/Servletdemo1">访问Servletdemo1</a>
在实际工程中最好使用绝对路径!!!
6. 案例需求介绍
6.1 案例需求描述
提供登录页面,用于用户登录(用户名和密码需要查询数据库)。如果登录失败,需要回到登录页面(给出提示信息)。如果登录成功,页面进行跳转,在成功页面上显示登录成功的总人数。
6.2 案例预习知识
6.2.1 Request作为域对象存取数据的方法
-
向request域中存数据
-
从request域中获取数据
-
从request域中移除数据
Request作为域对象作用范围
Request对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是一次请求范围。
一次请求范围: 从客户端浏览器向服务器发送一次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。
6.2.2 请求转发和重定向完成页面跳转
- Request请求转发
通过ServletRequest对象获得RequestDispatcher对象
再根据RequestDispatcher中的方法进行请求转发
- Response重定向
通过HttpServletResponse对象中的以下方法实现重定向
- 代码演示
package Servlet;
import java.io.IOException;
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;
/**
* 页面跳转测试
*/
@WebServlet("/Servletdemo2")
public class Servletdemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.请求转发的方式:
// RequestDispatcher dispatcher=request.getRequestDispatcher("/demo/demo1.jsp");
// dispatcher.forward(request, response);
//一步到位
// request.getRequestDispatcher("/demo/demo1.jsp").forward(request, response);
//2.重定向的方式
// response.sendRedirect("/web02/demo/demo1.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
6.2.3 请求转发和重定向区别
- 请求转发和重定向原理
请求转发和重定向区别总结 |
---|
请求转发是一次请求一次响应,而重定向是两次请求两次响应 |
请求转发地址栏不会变化的,重定向地址栏发生变化 |
请求转发路径不带工程名,重定向需要带工程名路径 |
请求转发只能在本网站内部,重定向可以定向到任何网站 |
- 代码演示
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<!-- demo1 -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>跳转后的页面。。。</h1>
<%= request.getAttribute("name") %>
</body>
</html>
package Servlet;
import java.io.IOException;
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;
/**
* 页面跳转测试
*/
@WebServlet("/Servletdemo2")
public class Servletdemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//向request域存数据
request.setAttribute("name", "司马老贼");
//1.请求转发的方式:
// RequestDispatcher dispatcher=request.getRequestDispatcher("/demo/demo1.jsp");
// dispatcher.forward(request, response);
//一步到位
// request.getRequestDispatcher("/demo/demo1.jsp").forward(request, response);
//能输出“司马老贼”
//2.重定向的方式
// response.sendRedirect("/web02/demo/demo1.jsp");
不能输出“司马老贼”,输出为null
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
注意:
如果需要使用request进行值传递,需要通过请求转发完成(输出“司马老贼”) !
如果页面需要跳转到其他网站上必须使用重定向!
7. 案例准备
7.1 MVC的准备
7.2 数据库创建
- 指令
create table user(
uid int primary key auto_increment,
username varchar(20),
password varchar(20),
nickname varchar(20)
);
insert into user values (null,'zs','123','张三');
insert into user values (null,'ls','123','李四');
insert into user values (null,'ww','123','王五');
- 图示(我用的是SQLyog)
7.3 项目搭建
7.4 引入相关资源
引入
- MySQL数据库驱动包
- C3P0连接池所需jar包
- DBUtils开发的jar包
- 将配置文件放到工程的src/main/java下即可
- 引入JDBC开发的工具类(JDBCUtils.java)
7.5 创建页面
7.5.1 登入页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<!-- login.jsp -->
<body>
<h1>登录页面</h1>
<form action="" method="post">
<table border="1" width="300">
<tr>
<td>用户名</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
</body>
</html>
7.5.2 登入成功页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>登录成功! </h1>
</body>
</html>
8. 案例代码
8.1 登录代码实现
流程:
登录页面(login.jsp)—> 登录的Servlet(LoginServlet),在这个Servlet中需要接收数据,将这个数据封装到一个JavaBean中,调用另一个JavaBean处理数据。根据处理结果进行页面跳转。
8.1.1 User.java
package com.zimo.domain;
public class User {
private int uid;
private String username;
private String password;
private String nickname;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
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;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
8.1.2 UserModel.java
package com.zimo.model;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import com.zimo.domain.User;
import com.zimo.utils.JDBCUtils;
/*
* 处理数据的javabean
*/
public class UserModel {
/*
* 处理用户登录的方法
*/
public User login(User user) throws SQLException {
System.out.println(user.getUsername() + "+" +user.getPassword());
// 连接数据库;通过传入用户名和密码去数据库中查询
QueryRunner queryrunner = new QueryRunner(JDBCUtils.getDataSource());
User existUser = queryrunner.query("select * from user where username = ? and password = ?",
new BeanHandler<User>(User.class), user.getUsername(), user.getPassword());
return existUser;
}
}
8.1.3 LoginServlet.java
package com.zimo.controller;
import java.io.IOException;
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 com.zimo.domain.User;
import com.zimo.model.UserModel;
/**
* 登录的Servlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收数据
request.setCharacterEncoding("UTF-8");
String username=request.getParameter("username");
String password=request.getParameter("password");
//2.封装数据
User user=new User();
user.setUsername(username);
user.setPassword(password);
//3.处理数据
UserModel usermodel=new UserModel();
User existUser=usermodel.login(user);
//4.页面跳转
if(existUser==null) {
//登录失败,向request域中保存一个错误信息
request.setAttribute("msg","用户名或密码错误");
//使用请求转发
request.getRequestDispatcher("/web/login.jsp").forward(request, response);
}else {
//登入成功,重定向
response.sendRedirect("/web03/web/success.jsp");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
8.1.4 JDBCUtils.java
package com.zimo.utils;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* JDBC的工具类
* @author jt
*
*/
public class JDBCUtils {
// 创建一个连接池:但是这个连接池只需要创建一次即可。
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
/**
* 获得连接的方法
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
/**
* 获得连接池:
*/
public static DataSource getDataSource(){
return dataSource;
}
/**
* 释放资源的方法
* 因为dbutil的jar本身自带释放,故不再需要释放资源
*/
// public static void release(Statement stmt,Connection conn){
// if(stmt != null){
// try {
// stmt.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// stmt = null;
// }
// if(conn != null){
// try {
// conn.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// conn = null;
// }
// }
//
// public static void release(ResultSet rs,Statement stmt,Connection conn){
// // 资源释放:
// if(rs != null){
// try {
// rs.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// rs = null;
// }
// if(stmt != null){
// try {
// stmt.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// stmt = null;
// }
// if(conn != null){
// try {
// conn.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// conn = null;
// }
// }
}
```java
8.2 登入失败错误信息回写
8.2.1 向request中保存错误信息
//4.页面跳转
if(existUser == null) {
//登录失败,向request域中保存一个错误信息
request.setAttribute("msg","用户名或密码错误");
//使用请求转发
request.getRequestDispatcher("/web/login.jsp").forward(request, response);
}
8.2.2 在login页面显示错误信息
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<!-- login.jsp -->
<body>
<h1>登录页面</h1>
<%
String msg="";
//判断request域中是否有错误信息(因为第一次服务器启动的时候,没有错误信息)
if(request.getAttribute("msg")!= null){
//取出错误信息
msg =(String)request.getAttribute("msg");
}
%>
<h3><font color="red"><%= msg %></font></h3>
<form action="/web03/LoginServlet" method="post">
<table border="1" width="300">
<tr>
<td>用户名</td>
<td ><input type="text" name="username"/></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
</body>
</html>
8.3 记录登录成功人数
8.3.1 流程图
8.3.2 创建InitServlet.java来初始化计数器
package com.zimo.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 初始化的Servlet
*/
//@WebServlet("/InitServlet")
public class InitServlet extends HttpServlet {
public void init() throws ServletException{
//初始化一个值为0
int count=0;
//将这个值存入ServletContext域中
this.getServletContext().setAttribute("count" , count);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
8.3.3 配置web.xm文件使服务器启动时初始化计数器
将这个Servlet配置成启动时加载
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.zimo.controller.InitServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>InitServlet</servlet-name>
<url-pattern>/InitServlet</url-pattern>
</servlet-mapping>
8.3.4 在success页面中显示登录人数
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>登录成功! </h1></br>
<%
int count = 0;
//判断ServletContext中是否有值
if(this.getServletContext().getAttribute("count")!=null){
count=(int)this.getServletContext().getAttribute("count");
}
%>
<h3>登入成功总人数:<%= count %></h3>
</body>
</html>