大数据正式16 分手后的思念是犯贱 2022-06-04 03:13 242阅读 0赞 # 大数据正式16 # ### EasyMall网站的注册页面的编写 ### * 注册功能前台页面 * 效果 * ![5AUg8to.png][] * 代码 * regist.html # # <!DOCTYPE HTML> <html> <head> <title>欢迎注册EasyMall</title> <meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="css/regist.css"/> </head> <body> <h1>欢迎注册EasyMall</h1> <form action="/servlet/RegistServlet" method="POST" onsubmit=""> <table> <tr> <td class="tds">用户名:</td> <td><input type="text" name="username"></td> </tr> <tr> <td class="tds">密码:</td> <td><input type="password" name="password"></td> </tr> <tr> <td class="tds">确认密码:</td> <td><input type="password" name="password2" ></td> </tr> <tr> <td class="tds">昵称:</td> <td><input type="text" name="nickname" ></td> </tr> <tr> <td class="tds">邮箱:</td> <td><input type="text" name="email" ></td> </tr> <tr> <td class="tds">验证码:</td> <td><input type="text" name="valistr"><img id="yzm_img" src="img/regist/yzm.png" style="cursor: pointer"/></td> </tr> <tr> <td colspan="2"> <input type="submit" value="注册用户"/> </td> </tr> </table> </form> </body> </html> * regist.css # # @charset "utf-8"; { border: 1px solid #999; } body{ background-image: url("../img/regist/zc.jpg"); background-position:top; font-family:"微软雅黑"; } h1{ width:300px; margin: 190px auto 0px; text-align: center; color:#990000; } form{ width:450px; margin: 30px auto 0px; } table{ margin: 0px auto 0px; } .tds{ text-align: right; font-size:18px; } td{ padding-top:10px; } input[type='text'],input[type='password']{ width:150px; height:22px; border: 1px solid #cccccc; } input[name='valistr']{ width:80px; } #yzm_img{ vertical-align: top; margin-left:5px; } input[type='submit']{ background-image: url("../img/regist/zcan01.jpg"); width:127px; height:44px; border-style:none; font-size:20px; color:white; font-weight:bold; } input[type='submit']:hover{ background-image: url("../img/regist/zcan02.jpg"); } span{ color:red; font-size:14px; } * img * yzm.png * ![bhsbf9X.png][] * zc.jpg * ![sDZjgIx.jpg][] * zcan01.jpg * ![dzc5p9l.jpg][] * zcan02.jpg * ![axAFiDg.jpg][] * 注册功能后台逻辑 * 思路 1. 获取全局配置数据【<context-param>下的数据:例如编码utf-8】 2. 解决乱码问题 1. 解决request的乱码: 1. 【post方式:request.setCharacterEncoding("utf-8")】 2. 【get方式:先解码,再编码new String(request.getParameter("key").getBytes("iso8859-1"),"utf-8")】 2. 解决Response的乱码: 1. 【字节:"".getBytes("编码")】 2. 【字符:response.setCharacterEncoding("编码")】 3. 浏览器解析乱码 1. 【setHeader(“Content-Type”,“text/html;charset=utf-8”)】 3. 获取表单数据 * request.getParameter(name); 4. 校验数据和合法性【真正的检验:js防君子,这里防小人】 1. 数据不能为空 2. 用户名不重复 3. 密码和确认密码一致 4. 邮箱格式 5. 密码格式 6. 验证码是否一致 5. 将数据存入数据库 1. 数据库连接池 2. 归档成合适的MySqlUtils工具类 6. 跳入指定的注册成功后的界面 * 代码 * RegisteSer # # package com.easymall.ser; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.easymall.exception.MsgException; import com.easymall.utils.MySqlUtils; @SuppressWarnings("serial") public class RegisteSer extends HttpServlet { private Connection conn = null; private PreparedStatement stat = null; private ResultSet rs = null; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 全局变量 try { // 0.获取应用参数 ServletContext sc = this.getServletContext(); String encode = sc.getInitParameter("encode"); // 1.解决requestpost请求乱码 解决response输出数据乱码 request.setCharacterEncoding(encode); response.setCharacterEncoding(encode); response.setContentType("text/html;charset=" + encode); // 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 (username == null || "".equals(username)) { throw new MsgException("用户名不能为空!"); } if (password == null || "".equals(password)) { throw new MsgException("密码不能为空!"); } if (password2 == null || "".equals(password2)) { throw new MsgException("确认密码不能为空!"); } if (!password.equals(password2)) { throw new MsgException("两次密码不一致!"); } if (nickname == null || "".equals(nickname)) { throw new MsgException("昵称不能为空!"); } if (email == null || "".equals(email)) { throw new MsgException("邮箱不能为空!"); } if (!email.matches("^\\w+@\\w+(\\.\\w+)+$")) { throw new MsgException("邮箱格式不正确!"); } if (valistr == null || "".equals(valistr)) { throw new MsgException("验证码不能为空!"); } // 4.存入数据库 // 判断账号是否重复 conn = MySqlUtils.getConn(); stat = conn.prepareStatement("select * from user where username=?"); stat.setString(1, username); rs = stat.executeQuery(); if (rs.next()) {// 账号重复 throw new MsgException("账号重复"); } else {// 账号不重复 stat = conn .prepareStatement("insert into user values(?,?,?,?)");// 账号,密码,昵称,邮箱 stat.setString(1, username); stat.setString(2, password); stat.setString(3, nickname); stat.setString(4, email); stat.executeUpdate(); } // 5.向浏览器报告成功 回到主页 response.getWriter().write("注册成功!正在前往主页------>>>"); response.setHeader("refresh", "1;url=/regist.html"); } catch (MsgException e) { String msg = e.getMessage(); response.getWriter().write(msg); response.setHeader("refresh", "1;url=/regist.html"); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } finally { // 关闭数据库 MySqlUtils.close(conn, stat, rs); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } ### 存在的问题 ### * 数据回显【域对象的使用】 * session和cookie的使用 * 验证码【ajax+禁用缓存】 * ajax:Asynchronous JavaScript and XML * 本质就是通过js技术,背着浏览器,在不影响当前浏览器对当前页面的访问的情况下,偷偷的和服务器进行交流 * ajax在web中很常见 1. 文字直播 2. 百度地图 3. 百度搜索框的提示 4. ... * 完全符合HTTP协议 * 原生方式:(例) # # <script type="text/javascript"> var myXmlHttpRequest; //获取ajax引擎对象 function getXmlHttpObject() { var xmlHttpRequest; if (window.ActiveXObject) { xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } else { xmlHttpRequest = new XMLHttpRequest(); } return xmlHttpRequest; } function getName() { var url = "doindex.jsp?username=" + document.getElementById("username").value; myXmlHttpRequest = getXmlHttpObject(); if (myXmlHttpRequest) {//获取xmlhttpobject成功 myXmlHttpRequest.open("get", url, true);//参数一:提交方式// 参数二:地址//参数三:是否异步 myXmlHttpRequest.onreadystatechange = name_chuli;//回调函数(有括号-调用函数,没有括号- 地址引用) myXmlHttpRequest.send(null);//null 针对的是“get”请求方式 } } function getPassword() { var url = "doindex.jsp"; myXmlHttpRequest = getXmlHttpObject(); if (myXmlHttpRequest) {//获取xmlhttpobject成功 var data = "data=" +encodeURI(document.getElementById("password").value); myXmlHttpRequest.open("post", url, true);//参数一:提交方式// 参数二:地址//参数三:是否异步 myXmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); myXmlHttpRequest.onreadystatechange = password_chuli;//回调函数(有括号-调用函数,没有括号- 地址引用) myXmlHttpRequest.send(data);//null 针对的是“get”请求方式 } } //chuli函数--判断状态 //readyState //0-open未被调用 //1-读取中 //2-已读取 //3-返回 //4-结束 function name_chuli() { if (myXmlHttpRequest.readyState == 4) { var returnText = myXmlHttpRequest.responseText; getObjectById("myres").innerHTML = returnText;//innerHTML获取的是body中的内容、value获取的是整个页面 } } function password_chuli() { if (myXmlHttpRequest.readyState == 4) { var returnText = myXmlHttpRequest.responseText; getObjectById("dopass").innerHTML = returnText; } } //函数--封装获取id对象 function getObjectById(id) { return document.getElementById(id); } </script> * jQuery方式的ajax 1. ajax # # $.ajax({ url: "test.html", context: document.body, success: function(){ $(this).addClass("done"); }}); 2. get方式的ajax # # $.get("test.php", function(data){ alert("Data Loaded: " + data); }); 3. post方式的ajax # # $.post(url, [data], [callback], [type]) * 前台的实时校验数据【先js吧--这个代码量有点大】 # # function checkForm() { var flag = true; flag = checkNull("username", "帐号不能为空!") && flag; flag = checkNull("password", "密码不能为空!") && flag; flag = checkNull("password2", "确认密码不能为空!") && flag; flag = checkNull("nickname", "昵称不能为空!") && flag; flag = checkNull("email", "邮箱不能为空!") && flag; flag = checkNull("valistr", "验证不能为空!") && flag; flag = checkEmail("email", "格式不正确,是个油箱吧!") && flag; flag = checkPassword("password", "两次密码不一致!") && flag; if (flag) { document.getElementById("form1").submit(); } else { return; } } function checkPassword(name, msg) { var password = document.getElementsByName(name)[0].value; var password2 = document.getElementsByName(name + "2")[0].value; setMsg(name + "2", ""); if ("" == password2) { setMsg(name + "2", "确认密码不能为空!"); return false; } if (("" != password2) && (password != password2)) { setMsg(name + "2", msg); return false; } return true; } function checkEmail(name, msg) { var value = document.getElementsByName(name)[0].value; var reg = /^\w+@\w+(\.\w+)+$/; setMsg(name, ""); if ("" == value) { setMsg(name, "邮箱不能为空!"); return false; } if ((!reg.test(value)) && ("" != value)) { setMsg(name, msg); return false; } return true; } function checkNull(name, msg) { var value = document.getElementsByName(name)[0].value; setMsg(name, ""); if ("" == value) { setMsg(name, msg); return false; } return true; } function setMsg(name, msg) { document.getElementById(name + "_msg").innerHTML = msg; } * 前台的实时校验数据【jQuery】 # # $(document).ready( function() { var canSubmit = true;//提交的标志 //用户名已存在检查(ajax) $("input[name='username']").blur( function() { if ($("input[name='username']").val() != "") { $.get("/UserNameHasServlet?" + $.param({ "username" : $( "input[name='username']") .val() }), function(data) { if ($.parseJSON(data).hasUser) { //提示该账户已有 $("input[name='username']") .next("span").text("用户名重复!"); canSubmit = false; } else { $("input[name='username']") .next("span").text(""); canSubmit = true; } }); } }); //两次密码的一致性检验(失去焦点) $("input[name='password2']").blur( function() { if ($("input[name='password2']").val() != "") { if ($("input[name='password']").val() != $( "input[name='password2']").val()) {//密码不一致 $("input[name='password2']").next("span") .text("密码不一致!"); canSubmit = false; } else { $("input[name='password2']").next("span") .text(""); canSubmit = true; } } }); //检查邮箱的格式是否正确 $("input[name='email']").blur(function() { var email_Reg = /^\w+@\w+(\.\w+)+$/; if ($(this).val() != "" && email_Reg.test($(this).val())) { $(this).next("span").text(""); canSubmit = true; } else { $(this).next("span").text("邮箱格式不正确!"); canSubmit = false; } }); //验证码切换(点击事件) $("#yzm_img").click( function() { $(this).attr( "src", "/ValiImageServlet?time=" + new Date().getTime()); }); //表单提交事件 $("form").submit(function() { //判断所有的输入框是否为空 $.each($("input[type!='submit']"), function() { if ($(this).val() == "") {//密码不一致 $(this).nextAll("span").text("数据不能为空!"); canSubmit = false; } else { $(this).nextAll("span").text(""); canSubmit = true; } }); return canSubmit; }); }); * URL编码 * java中的编解码 * URLEncoder.encode(String str,String encode) * URLDecoder.decode(String str,String encode) * js中的编解码 * 整体:encodeURI(url)-----这里用这个 * 传递参数:encodeURIComponent * js使用数据:escape * jQuery中的编解码 * $.param(\{"key":"value"\}) * 平常的浏览器和服务器会自动进行编解码,而ajax偷偷的绕过浏览器,所以得手动编解码 * 浏览器和服务之间是通过HTTP协议通讯的 * HTTP协议只支持iso8859-1字符集 1. iso8859-1里有的原样输出 2. iso8859-1里没有的字符,先按照指定编码转为相应的字节;然后装换为相应的16进制的数;最后最前面加上一个百分号; 3. 转化过程 * ![ywvuJ85.png][] * 验证码的生成过程【没你想的那么难】 * 图片展示 * ![Pl6QTgI.png][] * ![WVWsJBS.png][] * ![uUJY8E1.png][] # # package com.easymall.ser; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class ValiImageServlet extends HttpServlet { // 背景参数 private int base = 30; private int height = base; private int width = base * 4; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 禁止浏览器缓存图片 resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("Progma", "no-cache"); resp.setDateHeader("Expires", 0); // 创建内存中的图片 BufferedImage di = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取画布画背景 Graphics2D g2 = (Graphics2D) di.getGraphics(); // 填充矩形 g2.setColor(Color.white); g2.fillRect(0, 0, width, height); // 绘制边框 g2.setColor(Color.red); g2.drawRect(0, 0, width - 1, height - 1); // 写字 g2.setFont(new Font("微软雅黑", Font.BOLD, 25)); for (int i = 0; i < 4; i++) { g2.setColor(new Color(getRandom(0, 255),getRandom(0, 255),getRandom(0, 255))); int temp = getRandom(-45, 45); g2.rotate(temp / 180.0 * Math.PI, 10 + 30 * i, 20); g2.drawString(Integer.toString(getRandom(0, 10)), 10 + 30 * i, 20); g2.rotate(-temp / 180.0 * Math.PI, 10 + 30 * i, 20); } // 画干扰线 for (int i = 0; i < 3; i++) { g2.setColor(new Color(getRandom(0, 255),getRandom(0, 255),getRandom(0, 255))); g2.drawLine(getRandom(0, width), getRandom(0, height), getRandom(0, width), getRandom(0, height)); } // 画干扰点 for (int i = 0; i < 5; i++) { g2.setColor(new Color(getRandom(0, 255),getRandom(0, 255),getRandom(0, 255))); g2.drawOval(getRandom(0, width), getRandom(0, height), 5, 5); } // 画出图片 ImageIO.write(di, "JPG", resp.getOutputStream()); // 关闭画布 g2.dispose(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } // 获取随机数 private int getRandom(int start, int end) { Random random = new Random(); return start + random.nextInt(end - start); } } ### 补充 ### * 用户名校验【ajax所联系的servlet】 # # package com.easymall.ser; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; 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.MySqlUtils; public class UserNameHasServlet extends HttpServlet { private Connection conn = null; private PreparedStatement stat = null; private ResultSet rs = null; boolean hasUser = true;// 默认数据库有--防止出错 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { // 获取用户名并解决乱码 String username = new String(req.getParameter("username").getBytes( "iso8859-1"), "utf-8"); System.out.println(username); // 查询数据库中是否有此用户 conn = MySqlUtils.getConn(); stat = conn .prepareStatement("select * from user where username=? "); stat.setString(1, username); rs = stat.executeQuery(); hasUser = rs.next();// 用户名重复为true System.out.println(hasUser); } catch (SQLException e) { e.printStackTrace(); } finally { MySqlUtils.close(conn, stat, rs); } // 返回json格式的数据 resp.getWriter().write("{\"hasUser\":" + hasUser + "}"); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } } * 自定义异常类 # # package com.easymall.exception; @SuppressWarnings("serial") public class MsgException extends RuntimeException { public MsgException() { } public MsgException(String msg) { super(msg); } } * mysql工具类 # # 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; public class MySqlUtils { // 创建数据库连接池--数据连接池只允许有一个 private static ComboPooledDataSource cpds = new ComboPooledDataSource(); // 将构造函数私有化,不允许创建该实例 private MySqlUtils() { super(); } // 获取连接 public static Connection getConn() { Connection conn = null; try { conn = cpds.getConnection(); } catch (SQLException e) { // 没有获得数据库连接的异常处理[有待详细处理] throw new RuntimeException(e); } return conn; } // 关闭资源 public static void close(Connection conn, Statement stat, ResultSet rs) { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } finally { conn = null; } } if (stat != null) { try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } finally { stat = null; } } if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } finally { rs = null; } } } } * c3p0.properties # # c3p0.driverClass=com.mysql.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql://localhost:3306/easymall c3p0.user=root c3p0.password=root * 数据库 # # CREATE TABLE `user` ( `username` varchar(32) NOT NULL, `password` varchar(32) NOT NULL, `nickname` varchar(32) NOT NULL, `email` varchar(32) NOT NULL, PRIMARY KEY (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; * user表结构 * ![NCUuajw.png][] * web.xml # # <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 全局参数的设置 --> <context-param> <param-name>encode</param-name> <param-value>utf-8</param-value> </context-param> <!-- Servlet地址对应设置 --> <servlet> <servlet-name>RegisteSer</servlet-name> <servlet-class>com.easymall.ser.RegisteSer</servlet-class> </servlet> <servlet> <servlet-name>UserNameHasServlet</servlet-name> <servlet-class>com.easymall.ser.UserNameHasServlet</servlet-class> </servlet> <servlet> <servlet-name>ValiImageServlet</servlet-name> <servlet-class>com.easymall.ser.ValiImageServlet</servlet-class> </servlet> <!-- Servlet映射设置 --> <servlet-mapping> <servlet-name>RegisteSer</servlet-name> <url-pattern>/RegisteSer</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>UserNameHasServlet</servlet-name> <url-pattern>/UserNameHasServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ValiImageServlet</servlet-name> <url-pattern>/ValiImageServlet</url-pattern> </servlet-mapping> <!-- 欢迎页面 --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> * jar包 * c3p0-0.9.1.2.jar * mysql-connector-java-5.0.8-bin.jar * ajax图文资料 * ![z9DKKfE.jpg][] [5AUg8to.png]: https://i.imgur.com/5AUg8to.png [bhsbf9X.png]: https://i.imgur.com/bhsbf9X.png [sDZjgIx.jpg]: https://i.imgur.com/sDZjgIx.jpg [dzc5p9l.jpg]: https://i.imgur.com/dzc5p9l.jpg [axAFiDg.jpg]: https://i.imgur.com/axAFiDg.jpg [ywvuJ85.png]: https://i.imgur.com/ywvuJ85.png [Pl6QTgI.png]: https://i.imgur.com/Pl6QTgI.png [WVWsJBS.png]: https://i.imgur.com/WVWsJBS.png [uUJY8E1.png]: https://i.imgur.com/uUJY8E1.png [NCUuajw.png]: https://i.imgur.com/NCUuajw.png [z9DKKfE.jpg]: https://i.imgur.com/z9DKKfE.jpg
相关 大数据正式5 大数据正式5 常见的shell命令 管道命令 管道符| 将两个命令隔开,左边命令的输出就会作为管道右边命令的输入 连续使 旧城等待,/ 2022年06月06日 10:29/ 0 赞/ 234 阅读
相关 大数据正式2 大数据正式2 用户身份与用户组记录的文件 在Linux系统当中,默认情况下所有的系统上的账号信息都记录在/etc/passwd这个文件内(包括root用户), 快来打我*/ 2022年06月06日 08:38/ 0 赞/ 161 阅读
相关 大数据正式10 大数据正式10 jQuery 定义:jQuery是一个“写的更少”,但“做的更多”的轻量级JavaScript函数库 优势 1. 可 ゞ 浴缸里的玫瑰/ 2022年06月05日 06:24/ 0 赞/ 250 阅读
相关 大数据正式32 大数据正式32 Spring中的JDBC jar包准备 ![zW1gEQQ.png][] bean+properties普通配置 悠悠/ 2022年06月03日 08:44/ 0 赞/ 165 阅读
相关 大数据正式27 大数据正式27 Spring 先来张图简单看一下 ![oQySJMC.png][] spring框架的特点 1 悠悠/ 2022年06月03日 04:38/ 0 赞/ 144 阅读
相关 大数据正式37 大数据正式37 Maven 传统项目存在的弊端 1. 导入jar包得经验丰富 2. 传统项目打包方式不通用,不能很好的支持聚合项 左手的ㄟ右手/ 2022年06月02日 01:46/ 0 赞/ 157 阅读
相关 大数据正式36 大数据正式36 MyBatis的接口形式 注意两点 1. 接口名---namespace值对应 2. 方法名---id一致 淩亂°似流年/ 2022年06月02日 01:12/ 0 赞/ 261 阅读
相关 大数据正式34 大数据正式34 Spring+SpringMVC 小例子 效果图 ![hsIEQmd.png][] 功能说明 川长思鸟来/ 2022年06月02日 00:16/ 0 赞/ 274 阅读
还没有评论,来说两句吧...