因为上午上了课晚上就做了实验,所以讲解的例子就直接使用实验的例子,就不再重写一遍老师上课写的代码了
以下为本次上机实验要求:
按照要求编写代码:
根据要求分析:可以将是要分成4部分完成
用户注册&登陆
首先为所有功能创建一个主页:index.html,用于将所有功能需要的使用接口暴露给用户,方便用户的调用,也方便开发时对功能的测试与后期的维护
Insert title here
注册
登陆
EL表达式
JSTL标签库
查询全部商品
上述代码段将本次实验需要暴露给用户的所有接口都定义好了
在定义好主页之后需要为用户抽象一个JavaBean,用于封装每一个用户的数据,方便对每个用户数据的同一管理与调度
用户实体类:UserDao.java
package com.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.entity.CommUser;
public class UserDao {
private String url = "jdbc:mysql://localhost:3306/shopSystem";
private String user = "root";
private String password = "abc123456789";
private String driver = "com.mysql.jdbc.Driver";
Connection conn = null;
PreparedStatement ps = null;
//连接数据库
public Connection conn() {
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.print("连接数据库成功..");
return conn;
}
//新增用户信息
public boolean addUser(CommUser user) {
boolean flag = false;
//连接DB并获取连接对象
UserDao con = new UserDao();
conn = con.conn();
String sql = "INSERT INTO commuser(Account,Password,Nickname) VALUES(?,?,?)";
try {
ps = conn.prepareStatement(sql);
ps.setString(1,user.getAccount() );
ps.setString(2,user.getPassword() );
ps.setString(3,user.getNickname());
ps.execute();
flag = true;
} catch (SQLException e) {
e.printStackTrace();
}
return flag;
}
//查询用户数据
public boolean searchUser(String Account){
boolean flag = false;
//连接DB并获取连接对象
UserDao con = new UserDao();
conn = con.conn();
String sql = "select * from commuser where Account = ?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1, Account);
ResultSet rs = ps.executeQuery();
if(rs.next()) {
System.out.println("查询成功!");
flag = true;
}else {
System.out.println("查询失败!");
}
} catch (SQLException e) {
e.printStackTrace();
}
return flag;
}
public static void main(String args[]) {
UserDao conn = new UserDao();
conn.conn();
}
}
用户注册页面:regist.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
Insert title here
相应的servlet处理页面:registServlet.java(对用户输入为空时做了非法保护)
package com.servlets;
import java.io.IOException;
import java.io.PrintWriter;
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.entity.CommUser;
import com.dao.UserDao;
import com.entity.*;
@WebServlet("/regist")
public class registServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//System.out.print("连接成功.."); -- 测试与regist是否连接成功
//获取注册信息
String Account = request.getParameter("Account");
String Password = request.getParameter("Password");
String Nickname = request.getParameter("Nickname");
if(Account.equals("")||Password.equals("")||Nickname.equals("")) {
out.print("输入的账号或密码或用户名不能为空!3秒后跳转至注册页面");
String registURL = "http://localhost:8080/myShopSys/regist.jsp";
response.setHeader("Refresh","3;URL="+registURL);
}else {
//创建用户实体对象
CommUser user = new CommUser(Account, Password, Nickname);
UserDao dao = new UserDao();
dao.addUser(user);
out.print("注册成功!3秒后跳转至首页");
String indexURL = "http://localhost:8080/myShopSys/index.html";
response.setHeader("Refresh","3;URL="+indexURL);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
用户登陆页面:login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
Insert title here
相应的servlet处理页面:loginServlet.java(对用户输入为空时做了非法保护)
package com.servlets;
import java.io.IOException;
import java.io.PrintWriter;
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.dao.UserDao;
@WebServlet("/login")
public class loginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//System.out.print("连接成功.."); -- 测试login是否正常连接
String Account = request.getParameter("Account");
String Password = request.getParameter("Password");
if(Account.equals("")||Password.equals("")){
out.print("输入的用户名或密码不能为空!3秒后跳转至登陆页面");
String loginURL = "http://localhost:8080/myShopSys/login.jsp";
response.setHeader("Refresh","3;URL="+loginURL);
}else {
UserDao dao = new UserDao();
if(dao.searchUser(Account)) {
out.print("登陆成功!3秒后跳转至首页");
String indexURL = "http://localhost:8080/myShopSys/index.html";
response.setHeader("Refresh","3;URL="+indexURL);
}else {
out.print("请输入正确的用户名或密码!3秒后跳转至登陆页面");
String loginURL = "http://localhost:8080/myShopSys/login.jsp";
response.setHeader("Refresh","3;URL="+loginURL);
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
由以上1个html页面+两个jsp页面+两个servlet 就完成了用户注册+登陆的逻辑功能
编写商品查询DAO:在这部分代码中,涉及到了数据库的连接,以及对数据库中具体数据表的数据查找(包含无条件查找、按商品类别查找以及按商品编号查找三种)-- 这其中使用到了另外一种数据结构——集合list,用于存储从数据库中查询到的数据集,即将查到的每一行数据作为集合中的一个元素进行存储,由此就将数据库中查到的整张数据表就都存储下来了。在三种查找方式的最后都返回这按照条件查找到的数据表对应的集合
package com.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.entity.Goods;
import com.mysql.fabric.xmlrpc.base.Array;
public class GoodsDao {
private String url = "jdbc:mysql://localhost:3306/shopSystem";
private String user = "root";
private String password = "abc123456789";
private String driver = "com.mysql.jdbc.Driver";
private Connection conn = null;
private PreparedStatement ps = null;
private ResultSet rs = null;
//将该对象定义在外面减少在将结果集存入list链表时,while创建多个对象
Goods goods = null;
//连接数据库
public Connection conn() {
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.print("连接数据库成功..");
return conn;
}
//查询goods表中所有的数据 -- 不需要参数
//因为查询到的是一张数据表所以使用集合--链表来存储查询结果,< >中指定了该链表中存储的数据对象
//该处指定为goods类型 -- 因为查出来的一条数据就是按照JavaBean--goods类型存储的,所以要用对应的数据类型接收
//或者说按照数据表各个字段创建了一个可以接收其所有字段数据的实体类--Goods
public List getAllGoods() {
UserDao con = new UserDao();
conn = con.conn();
List goodsList = new ArrayList();
String sql = "select * from goods";
//获取预编译对象来发送sql语句到MySQL
try {
ps = conn.prepareStatement(sql);
//rs为结果集
rs = ps.executeQuery();
//将rs中的结果集进行提取,存入list中
while(rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
String type = rs.getString("type");
double price = rs.getDouble("price");
long total = rs.getLong("total");
String description = rs.getString("description");
goods = new Goods(id, name, type, price, total, description);
//将取到的商品实体存入列表,有多少个存多少个
goodsList.add(goods);
}
} catch (SQLException e) {
e.printStackTrace();
}
return goodsList;
}
public List getGoodsByType(String type){
UserDao con = new UserDao();
conn = con.conn();
List goodsList = new ArrayList();
String sql = "select * from goods where type=?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1, type);
rs = ps.executeQuery();
while(rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
String typec = rs.getString("type");
double price = rs.getDouble("price");
long total = rs.getLong("total");
String description = rs.getString("description");
goods = new Goods(id, name, typec, price, total, description);
//将取到的商品实体存入列表,有多少个存多少个
goodsList.add(goods);
}
} catch (SQLException e) {
e.printStackTrace();
}
return goodsList;
}
public List getGoodsById(String id){
UserDao con = new UserDao();
conn = con.conn();
List goodsList = new ArrayList();
String sql = "select * from goods where id=?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1, id);
rs = ps.executeQuery();
while(rs.next()) {
String idc = rs.getString("id");
String name = rs.getString("name");
String typec = rs.getString("type");
double price = rs.getDouble("price");
long total = rs.getLong("total");
String description = rs.getString("description");
goods = new Goods(idc, name, typec, price, total, description);
//将取到的商品实体存入列表,有多少个存多少个
goodsList.add(goods);
}
} catch (SQLException e) {
e.printStackTrace();
}
return goodsList;
}
public static void main(String args[]) {
GoodsDao conn = new GoodsDao();
conn.conn();
}
}
编写商品查询涉及的前端页面&后端做处理的servlet:
结合第一部分中编写的index.html页面上为用户暴露的功能接口为对应的超链接、表单编写对应的servlet进行服务
重要提示:这两个坑浪费了我接近一小时才解决
①在该部分中,最好是使用request对象的作用域在后端与前端之间传递数据,因为request是只有在请求时才会被调用的,而page是只在当前页面有用的、session是在本次会话中有效的、application是在服务器宕机/重启之前一直有效的,所以若使用page,数据根本传不到前端页面取进行数据展示,而session与application是可以将数据传到前端页面,且可以进行数据的展示,但是会出现“请求过的数据会一直出现的数据展示页面” -- 即若先请求查询了所有数据,在下次按照商品类型查找数据时,上一次查询到的所有数据也会显示出来,在做第三次查询时用商品id号进行查询,前两次无条件查询结果和按照商品类型查询结果也会显示出来,原因就是你使用了session/application的作用域很广,且只要你请求过的数据都会记录在其中,所以在之后的查询中还会显示你之前查询到的数据。而不是像request那样,只有你请求时才会将你所请求的数据显示出来
②在对应servlet处理好前端来的请求过后实现页面跳转时,因为在第①点中说过要使用request这个内置对象,所以在跳转时必须使用转发,即在第二课中提到的“request.getRequestDispatcher("showInfo.jsp").forward(request, response)”,这种方式是在服务器里面直接跳转至指定页面上,效率最高;与重定向相比之下,重定向是重新向服务器发起一次请求,所以重定向的效率更低。而在该处只能使用转发的原因是:因为requet只能用在转发上获取数据,Session转发或重定向都可以,但是浏览器关闭就没有了,Application只要服务器不停止,永远可用。 所以在使用request存储数据时必须使用转发才能使得前端页面能够获取到在servlet中存储的数据,用重定向前端是获取不到数据的(这个坑是最坑的,因为eclipse中不会有任何报错信息,但是前端页面上打死也显示不了从数据库中查到的数据信息)
服务无条件查找的servlet:GoodsSearchAll.java
package com.servlets;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;
import com.dao.GoodsDao;
import com.entity.Goods;
@WebServlet("/searchAll")
public class GoodsSearchAll extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
GoodsDao goods= new GoodsDao();
List goodsList = goods.getAllGoods();
request.setAttribute("allGoods", goodsList);
request.getRequestDispatcher("show.jsp").forward(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
服务按照商品类别查找的servlet:GoodsByType.java
package com.servlets;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;
import com.dao.GoodsDao;
import com.entity.Goods;
@WebServlet("/searchType")
public class GoodsByType extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String type = request.getParameter("type");
GoodsDao goods= new GoodsDao();
List goodsList = goods.getGoodsByType(type);
request.setAttribute("goodsType", goodsList);
request.getRequestDispatcher("show.jsp").forward(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
服务按照商品编号查找的servlet:GoodsById.java
package com.servlets;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;
import com.dao.GoodsDao;
import com.entity.Goods;
@WebServlet("/searchId")
public class GoodsById extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
GoodsDao goods= new GoodsDao();
List goodsList = goods.getGoodsById(id);
request.setAttribute("goodsId", goodsList);
request.getRequestDispatcher("show.jsp").forward(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
编写向用户展示查询结果的网页:show.jsp
在使用JSTL之前要导入相应的数据包
在这个页面中主要就涉及到了本节课的重点EL表达式&JSTL
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Insert title here
<%-- ${requestScope.allGoods}
--%>
数据查询结果如下
Id
Name
Type
Price
Total
Description
${goods.id}
${goods.name}
${goods.type}
${goods.price}
${goods.total}
${goods.description}
<%-- ${goods.id} ${goods.name} ${goods.type} ${goods.price} ${goods.total} ${goods.description}
--%>
${goods.id}
${goods.name}
${goods.type}
${goods.price}
${goods.total}
${goods.description}
${goods.id}
${goods.name}
${goods.type}
${goods.price}
${goods.total}
${goods.description}