JSP: Java Server Pages (ava服务器端页面),其实就在HTML中嵌入Java代码。
SUN公司提供了动态网页开发技术: Servlet. Servlet 自身有一些缺点, SUN公司发现了这些问题,推出了一个新的动态网页开发技术JSP。
Servlet的缺点:
Servlet 需要进行配置,不方便维护。
Servlet 很难向网页中输出HTML页面内容
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<h1>Hello JSP h1>
body>
html>
JSP需要发布到服务器中才可以运行的
发布项目到Tomcat中
访问JSP页面
运行结果:
运行原理:
JSP文件翻译成Java文件,将这个Java文件编译生成class文件,运行class文件,而class文件最终继承的是httpservlet。
JSP= HTML +Java代码+ JSP自身东西
JSP的脚本元素就是在JSP中嵌入Java代码。
语法:
<%!变量或方法声明%>
写在这个脚本中的代码,翻译成Servlet内部的成员变量或成员方法。、
因为Servlet是一个线程不安全类,所以不推荐使用。
用法:
<body>
<%!
//声明变量
int a=3;
%>
body>
语法: <%=表达式%>
写在这个脚本中的代码, 翻译成方法内部的out,prin();当中的内容,显示在页面上。
用法:
<%=
a
%>
运行结果后可以将声明便签好中的a输出到页面上
语法:
<% 程序代码%>
写在这个脚本中的代码, 翻译成方法内部的局部变量或方法内部代码片段。
用法:
推荐使用程序代码标签,而不是声明标签,因为声明标签是写在Servlet中,而Servlet是一个线程不安全类。
MVC模式简介
web开发中的路径问题
web开发中目录路径问题的解决
提供一些页面,在页面中会提供链接或者表单,当点击链接或者表单的时候需要进行提交,提交到Servlet中。从页面向Servlet发送请求的地址(路径)应该如何编写。
先创建一个动态web项目:
分别使用相对路径和绝对路径,使根目录下的demo1.jsp和demo1目录下的demo1.jsp,访问ServletDemo1。
相对路径的写法:
相对路径不是以 / 开头的。
是以 ./(当前路径)和 …/(上一层路径)开头的。
相对路径的使用:
在根路径下的页面访问Servlet
demo1的访问路径:
http://localhost:8080/web02/demo1.jsp
ServletDemo1的访问路径:
http://localhost:8080/web02/ServeltDemo1
在某个目录下的页面访问Servlet
demo1的访问路径:
http://localhost:8080/web02/demo1/demo1.jsp
ServletDemo1的访问路径:
http://localhost:8080/web02/ServeltDemo1
绝对路径的写法:
通常以 / 开始的路径
使用绝对路径,不需要关心当前文件和要请求的文件的相对位置的关系!!!
提供登录页面,用于用户登录(用户名和密码需要查询数据库)。如果登录失败,需要回到登录页面(给出提示信息)。如果登录成功,页面进行跳转,在成功页面上显示登录成功的总人数。
向Request域中保存数据
从Request域中获取数据
从Request域中移除数据
Request对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是一次请求范围。
一次请求范围:从客户端浏览器向服务器发送一次请求, 服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。
通过ServletReguest对象获得ReguestDispatcher对象
再根据RequestDispatcher中的方法进行请求转发
代码实现:
创建一个JSP 页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<h1>跳转后的页面h1>
body>
html>
创建一个Servlet
@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 请求转发的方式
/*
* RequestDispatcher dispatcher = request.getRequestDispatcher("/demo1.jsp");
* dispatcher.forward(request, response);
*/
// 也可以一条写完
request.getRequestDispatcher("/demo1.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
通过HttpServletResponse 对象中的以下方法实现重定向。
代码实现:
@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 2. 重新定向的方式
response.sendRedirect("/web02/demo1.jsp");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
请求转发与请求重定向的区别
请求转发和重定向的原理
总结:
请求转发是一次请求一次响应,而重定向是两次请求两次响应。
请求转发地址栏不会变化的,重定向地址栏发生变化。
请求转发路径不带工程名,重定向需要带工程名路径。
请求转发只能在本网站内部,重定向可以定向到任何网站。
使用请求转发
Servlet:
@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 向request域保存数据
request.setAttribute("name", 123);
// 请求转发的方式
request.getRequestDispatcher("/demo1.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<h1>跳转后的页面h1>
<%=request.getAttribute("name")%>
body>
html>
运行结果:
将request域中保存数据输出到了页面上
使用重定向
修改Servlet代码
@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 想request域保存数据
request.setAttribute("name", 123);
// 重新定向的方式
response.sendRedirect("/web02/demo1.jsp");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
运行结果:
输出request域中保存的数据时为null
总结:
如果需要使用request进行值传递,需要通过请求转发完成。如果页面需要调整到其他网站上必须使用重定向。
MVC设计模式在JavaWeb中的应用
MVC设计模式之业务逻辑分析
Create Table
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`nickname` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
)
创建web项目
创建相关包结构
controller:控制层
model:存放处理数据的Javabean
domain:存放数据封装的Javabean
utils:工具类
MySQL数据库驱动包
C3PO连接池所需jar包
DBUtils开发的jar包
引入c3p0配置文件,放到工程的src下即可。
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">
jdbc:mysql://localhost:3306/jdbc?useSSL=false&serverTimezone=UTC
</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">3</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">2</property>
<property name="maxStatements">200</property>
</default-config>
</c3p0-config>
/**
* JDBC的工具类
*
* @author 25858
*
*/
public class JDBCUtils {
// 创建连接池,创建连接池默认去类路径下查找c3p0-config.xml
// 创建一个连接池:但是这个连接池只创建一次即可。
private static final ComboPooledDataSource ds = new ComboPooledDataSource();
/**
* 获得连接的方法
*
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/**
* 获得连接池
*/
public static DataSource getDataSource() {
return ds;
}
}
<body>
<h1>登录页面h1>
<form action="" method="post">
<table>
<tr>
<td>用户名:td>
<td><input type="text" name="username">td>
tr>
<tr>
<td>密 码:td>
<td><input type="password" name="password">td>
tr>
<tr>
<td><input type="submit" value="登录">td>
tr>
table>
form>
body>
登录代码流程:
登录页面(login.jsp) →登录的Servlet (LoginServlet),在这个Servlet中需要接收数据,将这个数据封装到一个JavaBean中,调用另一个JavaBean处理数据。根据处理结果进行页面跳转。
登录代码实现:
**
* 用于处理数据的Javabean
*
* @author 25858
*
*/
public class User {
private Integer uid;
private String username;
private String password;
private String nickname;
//get、set方法省略
}
/**
* 用于处理数据的Javabean
*
* @author 25858
*
*/
public class UserModel {
/**
* 处理用户登录的方法
*
* @param user
* @return
*/
public User login(User user) {
// TODO 自动生成的方法存根
return null;
}
}
/**
*
* @author 25858
*
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// 1.接收数据
// 处理中文乱码
req.setCharacterEncoding("UTF-8");
String name = req.getParameter("username");
String password = req.getParameter("password");
// 2.封装数据
User user = new User();
user.setUsername(name);
user.setPassword(password);
// 3.处理数据
UserModel userModel = new UserModel();
User existUser = userModel.login(user);
// 4.页面跳转
if (existUser == null) {
// 登录失败
// 向request域中保存一个错误信息
req.setAttribute("msg", "用户名或密码错误!!!");
// 使用请求转发的方式进行页面跳转
req.getRequestDispatcher("/login.jsp");
} else {
// 登录成功
// 使用重定向的方式进行页面跳转
res.sendRedirect("/web_login/success.jsp");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
处理数据部分代码:
/**
* 用于处理数据的Javabean
*
* @author 25858
*
*/
public class UserModel {
/**
* 处理用户登录的方法
*
* @param user
* @return
* @throws SQLException
*/
public User login(User user) throws SQLException {
// 连接数据库:通过传入的用户名和密码去数据中查询
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
User existUser = qr.query("select * from user where username=? and password=?",
new BeanHandler<User>(User.class), user.getUsername(), user.getPassword());
return existUser;
}
}
<h1>登录页面h1>
<%
//判断request域中是否有错误信息: (第一次进入登录页面的时候,没有错误信息)
//如果有错误信息:显示错误信息
String msg = " ";
if (request.getAttribute("msg") != null) {
//有错误信息,显示错误信息
msg = (String) request.getAttribute("msg");
}
%>
<h3>
<font color="red"><%=msg%>font>
h3>
画图分析:
完成初始化操作
代码实现:
在服务器启动的时候初始化一个值为零,将这个值存入到ServletContext域中。
**
* 初始化的Servlet
* *将这个Servlet配置成启动加载
* @author 25858
*
*/
@WebServlet("/InitServlet")
public class InitServlet extends HttpServlet {
@Override
/**
* 初始化的方法
*/
public void init() throws ServletException {
// 初始一个值为0
int count = 0;
// 将这个值存入到ServletContext
this.getServletContext().setAttribute("count", count);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
将这个Servlet配置成启动时加载,在web.xml中配置
Servlet的启动时加载
<!-- 将InitServlet使用web.xml的方式配置 -->
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>con.wxw.controller.InitServlet</servlet-class>
<!-- 配置启动时加载 -->
<load-on-startup>2</load-on-startup>
</servlet>
记录登录成功的人数
// 4.页面跳转
if (existUser == null) {
// 登录失败
// 向request域中保存一个错误信息
req.setAttribute("msg", "用户名或密码错误!!!");
// 使用请求转发的方式进行页面跳转
req.getRequestDispatcher("/login.jsp").forward(req, res);
} else {
// 登录成功
// 记录登录成功的人数
// 将ServletContext中的值取出+1
int count = (int) this.getServletContext().getAttribute("count");
// 进行+1的操作
count++;
// 将+1的值放回ServletContext中去
this.getServletContext().setAttribute("count", count);
// 使用重定向的方式进行页面跳转
res.sendRedirect("/web_login/success.jsp");
}
在成功登录页面(success.jsp)上显示总人数
<body>
<%
Integer count = 0;
//判断,如果ServletContext中有值,获取并显示
if (this.getServletContext().getAttribute("count") != null) {
count = (Integer) this.getServletContext().getAttribute("count");
}
%>
<h3>
登录总人数:<%=count%>
</h3>
<h1>登录成功</h1>
</body>
链接:https://pan.baidu.com/s/1JuhpMXsXAOceewLeMcqB1Q
提取码:buzt