EasyMall网站
1.创建EasyMall的网站
1.1创建www.easymall.com虚拟主机
tomcat - conf - server.xml - 修改文件,添加host标签。
<Host name="www.easymall.com" appBase="D:/www.easymall.com">
修改hosts文件,在文件中添加127.0.0.1 www.easymall.com </Host>
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:<form action="<%=request.getContextPath() %>/RegistServlet" method="POST">
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( "<h1 align='center'><font color='red'>恭喜注册成功,3秒之后跳转到首页</font></h1>"); 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,书写内容如下:
<tr>
<!-- 通过三元表达式判断是否存在msg错误信息 -->
<td class="tds" colspan=2 style="text-align:center" ><font color='red'><%=request.getAttribute("msg")==null?"":request.getAttribute("msg") %></font></td>
</tr>
ii. 在username、nickname、email的input框身上添加value属性:
<!--从请求中读出请求参数username -->
<input type="text" name="username" value="<%=request.getParameter("username")==null?"":request.getParameter("username") %>" />
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', '炒鸡管理员', 'admin@tedu.cn');
insert into user values(null, '张飞', '123', '管理员', 'admin@tedu.cn');
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页面中的注册按钮会向后台发送请求,如果频繁点击会对服务器造成无端的压力甚至导致服务器宕机,应该在前台页面就将无效的请求拦截下来,避免服务器压力过大。<script type="text/javascript" src="js/jquery-1.4.2.js"></script> <script type="text/javascript"> //前台校验 var formObj = { "checkForm":function(){ var canSub = true; //非空校验 canSub = this.checkNull("username", "用户名不能为空") && canSub; canSub = this.checkNull("password", "密码不能为空")&& canSub; canSub = this.checkNull("password2", "确认密码不能为空")&& canSub; canSub = this.checkNull("nickname", "昵称不能为空")&& canSub; canSub = this.checkNull("email", "邮箱不能为空")&& canSub; canSub = this.checkNull("valistr", "验证码不能为空")&& canSub; //密码一致性校验 canSub = this.checkPassword()&& canSub; //邮箱格式校验 canSub = this.checkEmail()&& canSub; return canSub; }, "checkNull":function(name,msg){ //非空校验 var tag =$("input[name='"+name+"']").val(); //获取消息提示框span //清空操作 $("input[name='"+name+"']").nextAll("span").text(""); if(tag == ""){ $("input[name='"+name+"']").nextAll("span").text(msg).css("color","red"); return false; } return true; }, "checkPassword":function(){ //密码一致性校验 var password = $("input[name='password']").val(); var password2 = $("input[name='password2']").val(); if(password!="" && password2!="" && password != password2){ //如果密码不一致,则在span中书写提示 $("input[name='password2']").nextAll("span").text("两次密码不一致").css("color","red"); return false; } return true; }, "checkEmail":function(){ //邮箱格式校验 //获取用户输入的邮箱 var email = $("input[name='email']").val(); var reg = /\w+@\w+(\.\w+)+/; //校验 if(email!= "" &&!reg.test(email)){ $("input[name='email']").nextAll("span").text("邮箱格式不正确").css("color","red"); return false; } return true; } }; </script>
-
添加验证码图片(更新,点击的是时候刷新)
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()); }); });