EasyMall网站
1.创建EasyMall的网站
1.1创建www.easymall.com虚拟主机
tomcat - conf - server.xml - 修改文件,添加host标签。
修改hosts文件,在文件中添加127.0.0.1 www.easymall.com
1.2在MyEclipse中创建一个Web应用,名称为EasyMall,EasyMall 发布采用自定义发布的方式,点击发布按钮,添加EasyMall应用,选中下拉框的选项,修改下方地址栏中的路径,
然后将Web应用发布在刚才D盘的自动生成的www.easymall.com文件夹中,将应用的名称改为ROOT(缺省Web应用的名称)。
3.Web应用中添加首页
首页由三部分组成:head、foot、index
分三份的原因:一个网站中的所有页面一般都是由这三部分组成,头部分和尾部分会重复出现,这时我们可以将他们书写在某一个页面中,通过引入的方式和并成一个页面。如果头部分或尾部分需要修改,则只需修改head或foot页面即可。
动态导入
动态包含 ,需要修改buffer属性。buffer= 0kb,让缓冲区为0,不然会导致头和尾部分在一块。
<%request.getRequestDispatcher("/_head.jsp").include(request, response); %>
静态导入(静态包含)合并首页
在index.jsp中的body开始标签中,添加如下代码:
<%@include file="/_head.jsp" %>
在body结束标签之前添加如下代码:
<%@include file="/_foot.jsp" %>
注册功能
引入jsp文件。
a. 为_head.jsp页面中的注册a标签添加href地址
注册 (jsp表达式用于获取动态路径)
b. 修改regist.jsp页面
修改form标签的action:
c. 创建RegistServlet,并添加代码:
i. 创建RegistServlet时注意,映射路径为/RegistServlet
ii. 添加代码如下:
package com.easymall.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.easymall.utils.JDBCUtils;
import com.easymall.utils.WebUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
//注册servlet
public class RegistServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.请求参数乱码处理
request.setCharacterEncoding("utf-8");
//1.响应参数乱码处理
response.setContentType("text/html;charset=utf-8");
//2.获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String password2 = request.getParameter("password2");
String nickname = request.getParameter("nickname");
String email = request.getParameter("email");
String valistr = request.getParameter("valistr");
//3.非空校验
if(WebUtils.isNull(username)){
//变量中的内容不能为"" 变量本身不能为null
//请求转发
request.setAttribute("msg", "用户名不能为空");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
if(WebUtils.isNull(password)){
//变量中的内容不能为"" 变量本身不能为null
//请求转发
request.setAttribute("msg", "密码不能为空");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
if(WebUtils.isNull(password2)){
//变量中的内容不能为"" 变量本身不能为null
//请求转发
request.setAttribute("msg", "确认密码不能为空");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
if(WebUtils.isNull(nickname)){
//变量中的内容不能为"" 变量本身不能为null
//请求转发
request.setAttribute("msg", "昵称不能为空");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
if(WebUtils.isNull(email)){
//变量中的内容不能为"" 变量本身不能为null
//请求转发
request.setAttribute("msg", "邮箱不能为空");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
if(WebUtils.isNull(valistr)){
//变量中的内容不能为"" 变量本身不能为null
//请求转发
request.setAttribute("msg", "验证码不能为空");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
// 非空验证的方法(非空校验工具)
public class WebUtils {
// 在一个工具类中调用一个方法的时候,希望只通过类名.的方式调用,所以方发为静态的
private WebUtils(){}
public static boolean isNull(String tag){
return tag == null||"".equals(tag); // 常亮放在前面
}
}
//4.密码一致性校验
if(password!=null && password2!=null &&!password.equals(password2)){
//两次密码不一致则设置一个域属性msg,发送到前台regist.jsp页面。
request.setAttribute("msg", "两次密码不一致");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}
//5.邮箱格式校验
//书写邮箱正则
tring reg = "\\w+@\\w+(\\.\\w+)+";
f(email!= null && !email.matches(reg)){
//String字符串使用已有参数调用.matches方法与正则字符串校验
//邮箱格式不正确,则将错误信息保存在域属性msg中,发送到前台regist.jsp页面
request.setAttribute("msg", "邮箱格式不正确");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
//6.验证码校验
/TODO:session
//7.数据入库
//8.跳转到首页
response.getWriter().write(
"恭喜注册成功,3秒之后跳转到首页
");
response.setHeader("refresh", "3;url=http://www.easymall.com");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
d. 修改regist.jsp页面—修改错误提示信息样式 和用户信息回显
i. 在table中新添加一个tr,书写内容如下:
<%=request.getAttribute("msg")==null?"":request.getAttribute("msg") %>
ii. 在username、nickname、email的input框身上添加value属性:
" />
value属性是为了实现数据回显操作所设置的属性。属性值应该先判断是否为null,为null则显示"" 不为null就显示其中包含的数据。
e. 修改RegistServlet.java---插入数据到数据库中
i. 创建easymall数据库,在其中添加表user:
create database easymall;
use easymall;
create table user(
id int primary key auto_increment,
username varchar(100),
password varchar(100),
nickname varchar(100),
email varchar(100)
);
insert into user values(null, 'admin', '123', '炒鸡管理员', '[email protected]');
insert into user values(null, '张飞', '123', '管理员', '[email protected]');
ii. 添加JDBC相关内容:
1) 导入mysql驱动jar包
2) 手写JDBC6步
iii. 添加数据源
1) 导入c3p0的jar包
2) 在src目录下存放一个c3p0.properties文件
iv. 在RegistServlet中添加如下代码:
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//ComboPooledDataSource source = new ComboPooledDataSource();
//获取数据源
ComboPooledDataSource source = JDBCUtils.getPool();
//判断数据库中是否已有对应用户名
try {
conn = source.getConnection();
ps = conn.prepareStatement("select * from user where username = ?");
ps.setString(1, username);
rs = ps.executeQuery();
if(rs.next()){
//如果为true则证明用户名已存在
//向前台页面返回错误 提示
request.setAttribute("msg", "用户名已存在");
request.getRequestDispatcher("/regist.jsp").forward(request, response);
return;
}else{
//如果为false则证明用户名不存在
//可以注册
conn = source.getConnection();
ps = conn.prepareStatement("insert into user values(null,?,?,?,?)");
ps.setString(1, username);
ps.setString(2, password);
ps.setString(3, nickname);
ps.setString(4, email);
ps.executeUpdate();
}
} catch (SQLException e1) {
e1.printStackTrace();
}finally{
JDBCUtils.close(conn, ps, rs);
}
v. 编写JDBCUtils工具类:
package com.easymall.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mchange.v2.c3p0.ComboPooledDataSource;
//JDBC工具类
public class JDBCUtils {
//构造函数私有化
private JDBCUtils(){}
//c3p0数据源,每次产生一个对象,就会初始化一批连接,而我们只是用其中的一个,其他都造成了浪费。
//所以c3p0对象的应该只创建一次。
//创建静态数据源
public static ComboPooledDataSource pool = new ComboPooledDataSource();
//返回数据源对象
public static ComboPooledDataSource getPool(){
return pool;
}
//关闭资源
public static void close(Connection conn,Statement stat,ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;
}
}
if(stat != null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
stat = null;
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
前台校验(为了减少无效请求,后台校验是真正的校验)
点击regist.jsp页面中的注册按钮会向后台发送请求,如果频繁点击会对服务器造成无端的压力甚至导致服务器宕机,应该在前台页面就将无效的请求拦截下来,避免服务器压力过大。
添加验证码图片(更新,点击的是时候刷新)
a. 添加工具类 verifyCode.java
b. 修改regist.jsp页面中的img标签:
c. 创建ValidateServlet.java文件
package com.easymall.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.easymall.utils.VerifyCode;
//生成验证码的servlet
public class ValidateServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//验证码不能使用缓存图片,所以控制浏览器使用缓存
response.setDateHeader(“Expires”, -1);
response.setHeader(“Pragma”, “no-Cache”);
response.setHeader(“Cache-control”, “no-cache”);
//调用验证码工具类,生成一张验证码图片,发送到响应缓冲区中,最后会发送到浏览器中。
VerifyCode vc = new VerifyCode();
vc.drawImage(response.getOutputStream());
String code = vc.getCode();
System.out.println(“code:”+code);
System.out.println(“图片生成成功。”);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
d. 单击图片时切换验证码:
i. 在script标签中添加如下代码:
//文档就绪事件,在页面加载完成之后执行其中的代码
$(function(){
//为图片绑定单击事件
$("#img").click(function(){
//为图片绑定新的src属性值
$(this).attr("src","<%=request.getContextPath()%>/VlidateServlet?time="+new Date().getTime());
});
});