zoukankan      html  css  js  c++  java
  • hospital 基于反射的 在线医疗项目(二)

    一、登录/注册/验证码

    1. 登录、注册、主页等jsp前端页面准备

    ​ 1.1 、首先我们在WebContent 文件夹下创建static (静态文件夹),该文件夹是用来放置静态文件的,static文件夹创建css、js、img三个文件夹。同时创建jsp页面,起初要创建的页面如下图:

    hospital06

    ​ 1.2、当然,我们需要给出login.jsp的代码,使得我们不需要花费时间在样式上。

    <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
    <%
    	String path=request.getScheme()+"://"+request.getServerName()+":"+
    	request.getServerPort()+request.getContextPath()+"/";
    	pageContext.setAttribute("path", path);
    %>
    <!DOCTYPE html>
    <html>
    <head>
        <title>ONESTAR-在线医疗管理系统</title>
    	<meta charset="UTF-8">
    	<link rel="icon" href="static/img/me.jpg" type="image/x-icon" />
        <link rel="stylesheet" type="text/css" href="static/css/bootstrap.css" />
        <link rel="stylesheet" type="text/css" href="static/css/bootstrap-responsive.css" />
        <link rel="stylesheet" type="text/css" href="static/css/style.css" /> 
        <link rel="stylesheet" type="text/css" href="static/css/login-inner.css" />
        <!-- js -->
        <script type="text/javascript" src="static/js/jquery.js"></script>
        <script type="text/javascript" src="static/js/bootstrap.js"></script>
        <script type="text/javascript" src="static/js/ckform.js"></script>
        <script type="text/javascript" src="static/js/common.js"></script>
        <script type="text/javascript" src="static/js/jquery-3.4.1.js"></script>
        <!--表单验证  -->
        <script type="text/javascript" src="static/js/jquery.validate.js"></script>
        <script type="text/javascript" src="static/js/messages_zh.js"></script>
    
    </head>
    <body>
    	<div class="container">
    		
    	    <form class="form-signin" method="post" action="user" id="form-signin">
    	    	<input type="hidden" name="method" value="checkLogin">
    	        <h2 class="form-signin-heading" >在线医疗管理系统</h2>
    
    	        <p id="message" style=" 400px;height: 30px;text-align: center;"></p>
    	        <p><input type="text" name="username" class="input-block-level" value="lisi" placeholder="账号" ></p>
    	        <p><input type="password" name="password" class="input-block-level" placeholder="密码" value="321" >
    	        <p class="yanzhengma">
    	        	<input type="text" name="verify" class="input-medium" placeholder="验证码" > 
    	        	<img id="code" class="code_images"  src="${path }authImage" /> 
    	        	<a href='javascript:void(0);' onclick="javascript:changeImg()" style="color:white;text-decoration: none;">
    	        		<span style="color:blue;margin-left: 5px;">看不清?</span>
    	        		<span id= "yanzhengmaError"></span>
            		</a>
    				
    			</p>
    	        <p style="text-align: center;">
    	        <input id="login" type="button" value="登录" name="login" class="btn btn-large btn-primary" style=" 150px;"/>
    	        <a href="regist.jsp">请先注册</a>
    	        </p>
    	    </form>
    	</div>
    		
    	<script type="text/javascript">
    		function changeImg(){
    		    var img = document.getElementById("code"); 
    		    img.src = "${path}/authImage?date=" + new Date();;
    		}
    		
    	</script>
    </body>
    </html>
    

    1.3 register.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%
    	String path=request.getScheme()+"://"+request.getServerName()+":"+
    	request.getServerPort()+request.getContextPath()+"/";
    	pageContext.setAttribute("path", path);
    %>
    <!DOCTYPE html>
    <html>
    <head>
        <title>ONESTAR-在线医疗管理系统</title>
    	<meta charset="UTF-8">
    	<link rel="icon" href="static/img/me.jpg" type="image/x-icon" />
        <link rel="stylesheet" type="text/css" href="static/css/bootstrap.css" />
        <link rel="stylesheet" type="text/css" href="static/css/bootstrap-responsive.css" />
        <link rel="stylesheet" type="text/css" href="static/css/style.css" />
        <link rel="stylesheet" type="text/css" href="static/css/regist-inner.css" />
        <!-- js -->
        <script type="text/javascript" src="static/js/jquery.js"></script>
        <script type="text/javascript" src="static/js/bootstrap.js"></script>
        <script type="text/javascript" src="static/js/ckform.js"></script>
        <script type="text/javascript" src="static/js/common.js"></script>
        <script type="text/javascript" src="static/js/jquery-3.4.1.js"></script>
        <script type="text/javascript" src="static/js/jquery.validate.js"></script>
        <script type="text/javascript" src="static/js/messages_zh.js"></script>
    
    </head>
    <body>
    <div class="container">	
        <form class="form-signin" method="post" action="user" id = "form-signin">
        	<input type="hidden" name="method" value="regist">
            <h2 class="form-signin-heading" >管理员注册</h2>
            <p id="message" style=" 400px;height: 30px;text-align: center;"></p>
                            姓&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名:
    		<input type="text" name="name" class="input-block-level" placeholder="账号">
    		<br/>
                            密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码:
            <input id="password" type="password" name="password" class="input-block-level" placeholder="密码">
            <br/>
                           确认密码:<input type="password" name="password2" class="input-block-level" placeholder="确认密码">
            <br/>
                            用&nbsp;&nbsp;户&nbsp;&nbsp;名:<input type="text" id="username" name="username" class="input-block-level" placeholder="用户名">
            <span id="username_msg"></span><br/>
                            邮&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箱:<input type="text" id="email" name="email" class="input-block-level" placeholder="邮箱">
            <span id="email_msg"></span><br/>               
            <p style="text-align: center;">
            <input id=register type="button" value="注册" name="login" class="btn btn-large btn-info" style=" 100px;"/>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <input id="reset" type="reset" value="清空" name="login" class="btn btn-large btn-info" style=" 100px;"/>
            </p>
        </form>
    </div>
    
    </body>
    </html>
    
    2. 表单验证和图片验证码

    我们首先来讲图片验证码,让其能再登录页正常显示。

    ​ 1.1、页面验证码时,img标签的src路径是: src="${path }authImage",经解析后,实际上像后台请求的路径为:http://localhost:8080/hospital/authImage, 此时我们就需要在controller包中新建一个AuthImageServlet,注解路径为 @WebServlet("/authImage"),同时在util包创建生成验证码工具类 VerifyCodeUtils,两者代码如下:

    AuthImageServlet代码:

    package com.dzb.controller;
    
    import java.io.IOException;
    import javax.servlet.Servlet;
    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.dzb.util.VerifyCodeUtils;
    
    
    @WebServlet("/authImage")
    public class AuthImageServlet  extends HttpServlet implements Servlet{
    	
    	
    	static final long serialVersionUID = 1L; 
    	   
        public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
            response.setHeader("Pragma", "No-cache"); 
            response.setHeader("Cache-Control", "no-cache"); 
            response.setDateHeader("Expires", 0); 
            response.setContentType("image/jpeg"); 
            
            // 参数:date
            String date = request.getParameter("date");
            
            System.out.println("date:" + date);
            
            //生成随机字串 
            String verifyCode = VerifyCodeUtils.generateVerifyCode(4); 
            
            System.out.println("随机字符串:" + verifyCode);
            //存入会话session 
            HttpSession session = request.getSession(true); 
            
            System.out.println("Session:" + session);
            //删除以前的
            session.removeAttribute("verCode");
    
            session.setAttribute("verCode", verifyCode.toLowerCase()); 
            //生成图片 
            int w = 100, h = 30; 
            VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode); 
       
        } 
    	
    }
    
    

    工具类VerifyCodeUtils:

    package com.dzb.util;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Arrays;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    
    /**
     * 	生成验证码工具类
     * @author dzbiao
     *
     */
    public class VerifyCodeUtils {
    	// 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
    	public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    	private static Random random = new Random();
    
    	/**
    	 * 使用系统默认字符源生成验证码
    	 * 
    	 * @param verifySize 验证码长度
    	 * @return
    	 */
    	public static String generateVerifyCode(int verifySize) {
    		return generateVerifyCode(verifySize, VERIFY_CODES);
    	}
    
    	/**
    	 * 使用指定源生成验证码
    	 * 
    	 * @param verifySize 验证码长度
    	 * @param sources    验证码字符源
    	 * @return
    	 */
    	public static String generateVerifyCode(int verifySize, String sources) {
    		if (sources == null || sources.length() == 0) {
    			sources = VERIFY_CODES;
    		}
    		int codesLen = sources.length();
    		Random rand = new Random(System.currentTimeMillis());
    		StringBuilder verifyCode = new StringBuilder(verifySize);
    		for (int i = 0; i < verifySize; i++) {
    			verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
    		}
    		return verifyCode.toString();
    	}
    
    	/**
    	 * 生成随机验证码文件,并返回验证码值
    	 * 
    	 * @param w
    	 * @param h
    	 * @param outputFile
    	 * @param verifySize
    	 * @return
    	 * @throws IOException
    	 */
    	public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException {
    		String verifyCode = generateVerifyCode(verifySize);
    		outputImage(w, h, outputFile, verifyCode);
    		return verifyCode;
    	}
    
    	/**
    	 * 输出随机验证码图片流,并返回验证码值
    	 * 
    	 * @param w
    	 * @param h
    	 * @param os
    	 * @param verifySize
    	 * @return
    	 * @throws IOException
    	 */
    	public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException {
    		String verifyCode = generateVerifyCode(verifySize);
    		outputImage(w, h, os, verifyCode);
    		return verifyCode;
    	}
    
    	/**
    	 * 生成指定验证码图像文件
    	 * 
    	 * @param w
    	 * @param h
    	 * @param outputFile
    	 * @param code
    	 * @throws IOException
    	 */
    	public static void outputImage(int w, int h, File outputFile, String code) throws IOException {
    		if (outputFile == null) {
    			return;
    		}
    		File dir = outputFile.getParentFile();
    		if (!dir.exists()) {
    			dir.mkdirs();
    		}
    		try {
    			outputFile.createNewFile();
    			FileOutputStream fos = new FileOutputStream(outputFile);
    			outputImage(w, h, fos, code);
    			fos.close();
    		} catch (IOException e) {
    			throw e;
    		}
    	}
    
    	/**
    	 * 输出指定验证码图片流
    	 * 
    	 * @param w
    	 * @param h
    	 * @param os
    	 * @param code
    	 * @throws IOException
    	 */
    	public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
    		int verifySize = code.length();
    		BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    		Random rand = new Random();
    		Graphics2D g2 = image.createGraphics();
    		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    		Color[] colors = new Color[5];
    		Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA,
    				Color.ORANGE, Color.PINK, Color.YELLOW };
    		float[] fractions = new float[colors.length];
    		for (int i = 0; i < colors.length; i++) {
    			colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
    			fractions[i] = rand.nextFloat();
    		}
    		Arrays.sort(fractions);
    
    		g2.setColor(Color.GRAY);// 设置边框色
    		g2.fillRect(0, 0, w, h);
    
    		Color c = getRandColor(200, 250);
    		g2.setColor(c);// 设置背景色
    		g2.fillRect(0, 2, w, h - 4);
    
    		// 绘制干扰线
    		Random random = new Random();
    		g2.setColor(getRandColor(160, 200));// 设置线条的颜色
    		for (int i = 0; i < 20; i++) {
    			int x = random.nextInt(w - 1);
    			int y = random.nextInt(h - 1);
    			int xl = random.nextInt(6) + 1;
    			int yl = random.nextInt(12) + 1;
    			g2.drawLine(x, y, x + xl + 40, y + yl + 20);
    		}
    
    		// 添加噪点
    		float yawpRate = 0.05f;// 噪声率
    		int area = (int) (yawpRate * w * h);
    		for (int i = 0; i < area; i++) {
    			int x = random.nextInt(w);
    			int y = random.nextInt(h);
    			int rgb = getRandomIntColor();
    			image.setRGB(x, y, rgb);
    		}
    
    		shear(g2, w, h, c);// 使图片扭曲
    
    		g2.setColor(getRandColor(100, 160));
    		int fontSize = h - 4;
    		Font font = new Font("Algerian", Font.ITALIC, fontSize);
    		g2.setFont(font);
    		char[] chars = code.toCharArray();
    		for (int i = 0; i < verifySize; i++) {
    			AffineTransform affine = new AffineTransform();
    			affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1),
    					(w / verifySize) * i + fontSize / 2, h / 2);
    			g2.setTransform(affine);
    			g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
    		}
    
    		g2.dispose();
    		ImageIO.write(image, "jpg", os);
    	}
    
    	private static Color getRandColor(int fc, int bc) {
    		if (fc > 255)
    			fc = 255;
    		if (bc > 255)
    			bc = 255;
    		int r = fc + random.nextInt(bc - fc);
    		int g = fc + random.nextInt(bc - fc);
    		int b = fc + random.nextInt(bc - fc);
    		return new Color(r, g, b);
    	}
    
    	private static int getRandomIntColor() {
    		int[] rgb = getRandomRgb();
    		int color = 0;
    		for (int c : rgb) {
    			color = color << 8;
    			color = color | c;
    		}
    		return color;
    	}
    
    	private static int[] getRandomRgb() {
    		int[] rgb = new int[3];
    		for (int i = 0; i < 3; i++) {
    			rgb[i] = random.nextInt(255);
    		}
    		return rgb;
    	}
    
    	private static void shear(Graphics g, int w1, int h1, Color color) {
    		shearX(g, w1, h1, color);
    		shearY(g, w1, h1, color);
    	}
    
    	private static void shearX(Graphics g, int w1, int h1, Color color) {
    
    		int period = random.nextInt(2);
    
    		boolean borderGap = true;
    		int frames = 1;
    		int phase = random.nextInt(2);
    
    		for (int i = 0; i < h1; i++) {
    			double d = (double) (period >> 1)
    					* Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
    			g.copyArea(0, i, w1, 1, (int) d, 0);
    			if (borderGap) {
    				g.setColor(color);
    				g.drawLine((int) d, i, 0, i);
    				g.drawLine((int) d + w1, i, w1, i);
    			}
    		}
    
    	}
    
    	private static void shearY(Graphics g, int w1, int h1, Color color) {
    
    		int period = random.nextInt(40) + 10; // 50;
    
    		boolean borderGap = true;
    		int frames = 20;
    		int phase = 7;
    		for (int i = 0; i < w1; i++) {
    			double d = (double) (period >> 1)
    					* Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
    			g.copyArea(i, 0, 1, h1, 0, (int) d);
    			if (borderGap) {
    				g.setColor(color);
    				g.drawLine(i, (int) d, i, 0);
    				g.drawLine(i, (int) d + h1, i, h1);
    			}
    
    		}
    	}
    }
    
    

    1.2 验证码原理简析

    ​ 由前端传入日期参数date,通过工具类生成四位随机字符串,以小写形式存入session会话中,当前端需要更换验证码随机字符串时,也需要通过该流程,只是在此基础上添加了删除以前的session,即:session.removeAttribute("verCode"); 重新添加而已。

    1.3 表单验证

    ​ 表单验证实际上使用了jquery.validate.js 插件,我们可以在菜鸟教程上简单的学习一下用法。地址:https://www.runoob.com/jquery/jquery-plugin-validate.html

    hospital07

    ​ 表单验证使用name属性作为rules和messages的定位属性,因此我们必须在input 标签中声明name,与此同时 form标签添加 id定位 id="form-signin"。

    hospital08

    js 中的验证规则为:

    /* 表单验证 */
    $("#form-signin").validate({
        errorPlacement: function(error, element) {
            if (element.parent().hasClass("yanzhengma")){
                error.appendTo($("#yanzhengmaError"));     // 将错误信息添加到id为 yanzhengmaError中
            }else {					
                error.insertAfter(element);
            }
        },
        onfocusout: function(element) { $(element).valid(); },
        rules:{		// 规则	
            username:{		// 用户名
                required:true
            },
            password:{		// 密码
                required:true
            },
            verify:{	   // 验证码
                required:true
            }                    
        },
        messages:{
            username:{
                required:"用户名不能为空"
            },
            password:{
                required: "密码不能为空"
            },
            verify:{
                required: "验证码不能为空"
            }                                    
        },
        errorElement: "em"
    });
    

    当我们点击提交按钮的时候,我们如何获取表单数据是否验证成功的提示呢?所以我们通过 var flag = $("#form-signin").valid();获取,当表单的所有值都按照我们的要求通过后,flag 为true,反之,为false,基于这一点,我们判断是否提交。

    // 提交按钮 点击触发
    $("#login").click(function(){
        var flag = $("#form-signin").valid();
        if(!flag){
            //没有通过验证
            alert("没有通过验证");
            return;
        }
        var data = $("#form-signin").serialize();
        $.ajax({
            url:"user/login",
            type:"post",
            data:data,
            dataType:"json",
            success:function(message){
                console.log(message);
                if(message.status_code == 200){
                    $("#message").css("color","green");
    
                    setTimeout(function(){
    
                        location.href = "${path}"+"index.jsp";
                    },1000) ;
    
                }else{
                    $("#message").css("color","red");
                }
                $("#message").text(message.message);
            }
        });
    });
    

    1.4 同理,注册页面的表单验证也如登录页一样,在这就不多说,直接粘贴在register.jsp页面中。直接上代码:

    <script type="text/javascript">
    /* 表单验证 */
    $("#form-signin").validate({
    	
    	onfocusout: function(element) { $(element).valid(); },
    	rules:{
    		name:{
                required:true
            },
            password:{
                required:true
            },
            password2:{
            	required:true,
            	equalTo:"#password"
            } ,
            username:{
            	required:true,
            },
            email:{
            	required:true,
            	email:true
            }
        },
        messages:{
        	name:{
                required:"用户名不能为空"
            },
            password:{
                required: "密码不能为空"
            },
            password2:{
            	required: "确认密码必须和密码一样"
            } ,
            username:{
            	required: "用户昵称不能为空"
            },
            email:{
            	required: "邮箱格式不正确"
            }
        },
        errorElement: "em"
    });
    
    // 表单提交
    $("#register").click(function(){
    	var flag = $("#form-signin").valid();
    	if(!flag){
    		//没有通过验证
    		alert("没有通过验证");
            return;
    	}
    	var data = $("#form-signin").serialize();
    	$.ajax({
    		url:"user/register",
    		type:"post",
    		data:data,
    		dataType:"json",
    		success:function(message){
    			console.log(message);
    			console.log(message.status_code);
    			console.log(message.message);
    			if(message.status_code == 200){
    				$("#message").css("color","green");
    				setTimeout(function(){
    
    					location.href = "${path}";
    				},1000) ;
    				
    			}else{
    				$("#message").css("color","red");
    			}
    			$("#message").text(message.message);
    		}
    	});
    });
    </script>
    
    3.后端User模块的创建准备
    1. 首先我们在entity包下创建 实体类:USers.java
    package com.dzb.entity;
    
    import java.util.Date;
    
    /**
     * Bean : Users实体类
     * @author dzb
     */
    public class Users {
    	
    	private Integer uid; // 用户编号
    	private String name ; // 用户名
    	private String email; // 邮箱地址
    	private Integer status ; // 用户状态: 1 表示普通用户,0 表示管理员
    	private String username; // 用户昵称
    	private String password ; // 密码
    	private Date modifytime; // 修改时间 
    
    	public Users() {}	 // 无参构造一定要加
    		
    	public Users(String username, String password) {
    		super();
    		this.username = username;
    		this.password = password;
    	}
    
    	public Users(String name, String email, Integer status, String username, String password) {
    		super();
    		this.name = name;
    		this.email = email;
    		this.status = status;
    		this.username = username;
    		this.password = password;
    	}
    
    	public Users(String name, String email, Integer status, String username, String password, Date modifytime) {
    		this.name = name;
    		this.email = email;
    		this.status = status;
    		this.username = username;
    		this.password = password;
    		this.modifytime = modifytime;
    	}
    	
    	public Integer getUid() {
    		return uid;
    	}
    
    	public void setUid(Integer uid) {
    		this.uid = uid;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String getEmail() {
    		return email;
    	}
    	public void setEmail(String email) {
    		this.email = email;
    	}
    	public Integer getStatus() {
    		return status;
    	}
    	public void setStatus(Integer status) {
    		this.status = status;
    	}
    	public String getUsername() {
    		return username;
    	}
    	public void setUsername(String username) {
    		this.username = username;
    	}
    	public String getPassword() {
    		return password;
    	}
    	public void setPassword(String password) {
    		this.password = password;
    	}
    	public Date getModifytime() {
    		return modifytime;
    	}
    	public void setModifytime(Date modifytime) {
    		this.modifytime = modifytime;
    	}
    	@Override
    	public String toString() {
    		return "Users [uid=" + uid + ", name=" + name + ", email=" + email + ", status=" + status + ", username="
    				+ username + ", password=" + password + ", modifytime=" + modifytime + "]";
    	}
    }
    
    
    1. 和mysql 连接的DruidUtils.java 工具类。所有工具类地址:https://gitee.com/duanxiaobiao/hospital-jsp/tree/master/src/com/dzb/util

    2. 我们还需要创建一个Message类作为我们返回json数据封装的实体类:

    package com.dzb.entity;
    
    import java.util.List;
    import java.util.Map;
    
    public class Message {
    	
    	private Integer status_code;
    	
    	private String message;
    	
    	private Map<String, List> map;
    	
    	public Message() {}
    
    	public Message(Integer status_code, String message) {
    		super();
    		this.status_code = status_code;
    		this.message = message;
    	}
    	public Integer getStatus_code() {
    		return status_code;
    	}
    	public void setStatus_code(Integer status_code) {
    		this.status_code = status_code;
    	}
    	public String getMessage() {
    		return message;
    	}
    	public void setMessage(String message) {
    		this.message = message;
    	}
    	@Override
    	public String toString() {
    		return "Message [status_code=" + status_code + ", message=" + message + "]";
    	}
    	public Map<String, List> getMap() {
    		return map;
    	}
    	public void setMap(Map<String, List> map) {
    		this.map = map;
    	}
    }
    
    1. 实体类和工具类完成后,我们就开始按照顺序建立User模块需要的类:UserServlet --> UserService --> UserServiceImpl --> UserDao --> UserDaoImpl (这种分层,我原意是想仿照springmvc 项目的controller --> service -->serviceImpl -->dao -->mapper分层结构)。注意:要创建在对应的包下。完成后项目节后如下:

    hospital09

    4.登录逻辑
    1.controller层

    ​ 我们开始编写controller层中UserServlet类中login方法逻辑:我们期望将验证码参数和session中存储的验证码参数向比较,相等则进行登录查询验证,验证成功后将用户数据存储进session中,并设置有效时间。

    hospital-login-code

    而返回json数据的关键在于:

    // 要返回的消息实体
    Message message = new Message();
    ObjectMapper mapper  = new ObjectMapper();
    // 写response
    json = mapper.writeValueAsString(message);
    response.getWriter().print(json);
    

    UserServlet的login方法的完整逻辑如下:

    UserService userService = new UserServiceImpl(); // 这个放置在类序列号下即可
    
    public void login(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException  {
    		
        // 设置编码格式
        response.setCharacterEncoding("UTF-8");
    
        // 消息实体
        Message message = new Message();
        ObjectMapper mapper  = new ObjectMapper();
        String json = null;
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String verify = request.getParameter("verify");
    
        HttpSession session = request.getSession();
        String sessionVerify = (String) session.getAttribute("verCode");
    
        Users user = new Users(username,password);
        HttpSession sessionUser = request.getSession();
    
        if(!(verify.toLowerCase().equals(sessionVerify))) {
            message.setStatus_code(100);
            message.setMessage("验证码不正确");
        }else {
            boolean isExist = userService.checkUser(user);
    
            if(isExist) {
                // 存在允许登录;
                message.setStatus_code(200);
                message.setMessage("登录成功");
                System.out.println(user);
                sessionUser.setAttribute("user", user.getUsername());
                sessionUser.setMaxInactiveInterval(1*60*60);
                System.out.println("Session已经设置!一小时后失效.");
            }else {
                // 不存在登录失败;
                message.setStatus_code(100);
                message.setMessage("用户名或密码错误,登录失败");
            }
    
        }
        // 写response
        json = mapper.writeValueAsString(message);
        response.getWriter().print(json);	
    }
    
    2.UserService层

    UserService 接口添加 该方法 :

    /***
    *   检查用户
    * @param user
    * @return
    */
    boolean checkUser(Users user);
    
    3.UserServiceImpl实现层

    UserServiceImpl 实现类添加:

    UserDao userDao = new UserDaoImpl();
    @Override
    public boolean checkUser(Users user) {
        // TODO Auto-generated method stub
        return userDao.checkUser(user);
    }
    
    4.UserDao层

    UserDao 接口添加 :

    boolean checkUser(Users user);
    
    5.UserDaoImpl 层

    UserDaoImpl 添加:

    // 获取资源连接
    private QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
    
    /**
    * 检查用户是否存在
    */
    @Override
    public boolean checkUser(Users user) {
        String sql = "select * from users where username = ? and password = ?";
    
        Users u = null;
        try {
        	u = qr.query(sql, new BeanHandler<Users(Users.class),user.getUsername(),user.getPassword());
        } catch (SQLException e) {
        	e.printStackTrace();
        }
        if(u != null) {
        	return true;
        }else {
        	return false;
        }
    }
    
    5.注册逻辑

    ​ 和登录逻辑一样,我就不详细说了。直接粘贴各层代码。

    controller层
    public void register(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException, IllegalAccessException, InvocationTargetException  {
        // 设置编码格式
        response.setCharacterEncoding("UTF-8");
        // 消息实体
        Message message = new Message();
        ObjectMapper mapper  = new ObjectMapper();
        String json = null;
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        String password2 = request.getParameter("password2");
        String username = request.getParameter("username");
        String email = request.getParameter("email");
        System.out.println("password:" + password);
        System.out.println("password2:" + password2);
        String[] paraArr = new  String[] {name,password,password2,username,email};
        // 检查参数是否为空.
        boolean isEmpty = ParaCheck.isEmpty(paraArr);
    
        if(isEmpty) {message.setStatus_code(100);message.setMessage("参数不能为空");}
    
        // 检查用户密码和确认密码是否一致
        boolean isEqual = password.equals(password2);
        if(!isEqual) {
            message.setStatus_code(100);
            message.setMessage("密码和确认密码不一致.");
    
        }else if(!ParaCheck.emailFormat(email)) { // 检查email格式是否正确。
            message.setStatus_code(100);
            message.setMessage("邮箱格式不合法");
        }else { // 验证后:
            System.out.println("数据通过验证,开始存储数据.");
            Users user = new Users(name,email,1,username,password,new Date());
            // 首先查询是否存在该用户
            boolean isExist = userService.isExistUser(user);
            if(!isExist) {
                // 不存在则注册
                int result = userService.insertUser(user);
                if(result == 1) {
                    message.setStatus_code(200);
                    message.setMessage("注册成功");
                    Map<String ,String> map = new HashMap<String, String>();
                    map.put(user.getUsername(),user.getPassword());
                    //					message.setMap(map);
                }else {
                    // 添加失败
                    message.setStatus_code(100);
                    message.setMessage("添加失败");
                }
    
            }else {
                // 存在则返回失败信息
                message.setStatus_code(100);
                message.setMessage("用户昵称已存在!");
            }
        }
        // 写response
        json = mapper.writeValueAsString(message);
        response.getWriter().print(json);
    }
    
    Userservice层添加
    	/**
    	 *  查询是否存在该用户:
    	 * @param user
    	 * @return
    	 */
    	boolean isExistUser(Users user);
    	
    	/**
    	 *  添加用户
    	 * @param user
    	 * @return
    	 */
    	int insertUser(Users user);
    
    UserServiceImpl层 添加 :
    /**
    *  查询是否存在用户
    */
    @Override
    public boolean isExistUser(Users user) {
    
    	return userDao.isExistUser(user);
    }
    
    /**
    * 添加用户
    */
    @Override
    public int insertUser(Users user) {
        // TODO Auto-generated method stub
        return userDao.insertUser(user);
    }
    
    UserDao层
    boolean isExistUser(Users user);
    
    /**
    *  添加用户
    * @param user
    * @return
    */
    int insertUser(Users user);
    
    UserDaoImpl 层
    /**
    *  查询用户是否存在
    */
    @Override
    public boolean isExistUser(Users user) {
    	String sql = "select * from users where username = ? ";
    		
        Users u = null;
        try {
            u = qr.query(sql, new BeanHandler<Users>(Users.class),user.getName());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if(u != null) {
            return true;
        }else {
            return false;
        }
    
    }
    
    /**
    *  添加用户
    */
    @Override
    public int insertUser(Users user) {
        String sql = "insert into users(name,email,status,username,password,modifytime) values(?,?,?,?,?,?)";
        int result = 0;
        try {
            result = qr.update(sql, user.getName(),user.getEmail(),user.getStatus(),user.getUsername(),
                               user.getPassword(),user.getModifytime());
        } catch (SQLException e) {
            System.out.println(e);
            System.out.println("Insert方法添加失败。");
        }
        return result;
    }
    

    结尾

    第二章实现了项目框架的搭建,图形验证码、登录、注册功能等模块的实现,下一章 构建页面的列表页,分页、增删改查等基本功能。

    该篇完整代码地址:https://gitee.com/duanxiaobiao/hospital-jsp

  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/duanxiaobiao/p/14428053.html
Copyright © 2011-2022 走看看