19、Javaweb案例-登录功能

news2024/11/15 12:28:47

项目导入

选择travel项目的pom.xml文件,点击ok,完成项目导入。需要等待一小会,项目初始化完成。

启动项目

方式一:

 方式二:配置maven快捷启动

技术选型

Web层

  1. Servlet:前端控制器
  2. html:视图
  3. Filter:过滤器
  4. BeanUtils:数据封装
  5. Jackson:json序列化工具

Service层

  1. Javamail:java发送邮件工具
  2. Redis:nosql内存数据库
  3. Jedis:java的redis客户端

Dao层

  1. Mysql:数据库
  2. Druid:数据库连接池
  3. JdbcTemplate:jdbc的工具

创建数据库

-- 创建数据库

CREATE DATABASE travel;

-- 使用数据库

USE travel;

--创建表

复制提供好的sql

注册功能

页面效果

 功能分析

 代码实现

前台代码实现

User具体类

package cn.itcast.travel.domain;

import java.io.Serializable;

/**
 * 用户实体类
 */
public class User implements Serializable {
    private int uid;//用户id
    private String username;//用户名,账号
    private String password;//密码
    private String name;//真实姓名
    private String birthday;//出生日期
    private String sex;//男或女
    private String telephone;//手机号
    private String email;//邮箱
    private String status;//激活状态,Y代表激活,N代表未激活
    private String code;//激活码(要求唯一)

    /**
     * 无参构造方法
     */
    public User() {
    }

    /**
     * 有参构方法
     * @param uid
     * @param username
     * @param password
     * @param name
     * @param birthday
     * @param sex
     * @param telephone
     * @param email
     * @param status
     * @param code
     */
    public User(int uid, String username, String password, String name, String birthday, String sex, String telephone, String email, String status, String code) {
        this.uid = uid;
        this.username = username;
        this.password = password;
        this.name = name;
        this.birthday = birthday;
        this.sex = sex;
        this.telephone = telephone;
        this.email = email;
        this.status = status;
        this.code = code;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    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 String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

响应信息具体类

package cn.itcast.travel.domain;

import java.io.Serializable;
import java.util.Objects;

/**
 * 用于封装后端返回前端数据对象
 */
public class ResultInfo implements Serializable {
    private boolean flag;//后端返回结果正常为true,发生异常返回false
    private Object data;//后端返回结果数据对象
    private String errorMsg;//发生异常的错误消息

    //无参构造方法
    public ResultInfo() {
    }
    public ResultInfo(boolean flag) {
        this.flag = flag;
    }
    /**
     * 有参构造方法
     * @param flag
     * @param errorMsg
     */
    public ResultInfo(boolean flag, String errorMsg) {
        this.flag = flag;
        this.errorMsg = errorMsg;
    }
    /**
     * 有参构造方法
     * @param flag
     * @param data
     * @param errorMsg
     */
    public ResultInfo(boolean flag, Object data, String errorMsg) {
        this.flag = flag;
        this.data = data;
        this.errorMsg = errorMsg;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public ResultInfo setResultInfo(ResultInfo info,boolean flag, Object data, String errorMsg) {
        info.setFlag(flag);
        info.setData(data);
        info.setErrorMsg(errorMsg);
        return info;
    }

}

JDBCUtils工具类

UuidUtil:产生UUID随机字符串工具类

邮箱工具类详情

验证码

前台

表单校验

提升用户体验,并减轻服务器压力。

异步(ajax)提交表单

在此使用异步提交表单是为了获取服务器响应的数据。因为我们前台使用的是html作为视图层,不能够直接从servlet相关的域对象获取值,只能通过ajax获取响应数据

注册页面

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>注册</title>
        <link rel="stylesheet" type="text/css" href="css/common.css">
        <link rel="stylesheet" href="css/register.css">
		<!--导入jquery-->
		<script src="js/jquery-3.3.1.js"></script>
    </head>
	<script>
		//constants
		const username = "#username";
		const password = "#password";
		const notarize_password = "#notarizepassword";
        const email = "#email";
		const name="#name";
		const telephone = "#telephone";
		const birthday = "#birthday"
		const check_code_info = "#check";
		const errorMsg = "#errorMsg"
		const registerForm = "#registerForm"
		//method
		function border_null(value) {
			return $(value).css("border", "") && true
		}
		function border_red(value) {
			return $(value).css("border", "1px solid red") && false
		}
		function check(value,reg){
			return reg.test($(value).val())
					? border_null(value)
					: border_red(value);
		}
		function checkLength(value,length){
			let $value = $(value);
			return $value.val().length==length
					? border_null(value)
					: border_red(value);
		}
		//logic
		function checkUsername(){
			let reg_value = /^\w{8,20}$/;
			return check(username, reg_value);
		}
		function checkPassword(){
			let reg_value = /^\w{8,20}$/;
			return check(password, reg_value);
		}
		function checkNotarizePassword() {
			let npswdval = $(notarize_password);
			return npswdval.val() == $(password).val()
					? border_null(notarize_password)
					: border_red(notarize_password);
		}
		function checkEmail(){
			let reg_value = /^\w+@\w+\.\w+$/;
			return check(email,reg_value)
		}
		function checkName(){
			let reg_value = /^[a-zA-Z0-9_\u4e00-\u9fa5]{3,50}$/;
			return check(name,reg_value)
		}
		function checkTelePhone(){
			let reg_value = /^[1-9]{11}$/;
			return check(telephone,reg_value)
		}
		function checkBirthDay(){
			return checkLength(birthday, 10)
		}
		function checkCode(){
			return checkLength(check_code_info, 4)
		}
		function ischeck(){
			return checkUsername()
					&& checkPassword()
					&& checkNotarizePassword()
					&& checkEmail()
					&& checkName()
					&& checkTelePhone()
					&& checkBirthDay()
					&& checkCode()
		}
		//execute
		$(()=>{
			$(registerForm).submit(function (){
				if(ischeck()){
					$.post('registerUserServlet',$(this).serialize(),function(data){
						data.flag
								?location.href="register_ok.html"
								:$(errorMsg).html(data.errorMsg).css("color", "red");
					})
				}
				return false;
			})
			//失去焦点
			$(username).blur(checkUsername);
			$(password).blur(checkPassword);
			$(notarize_password).blur(checkNotarizePassword);
			$(email).blur(checkEmail);
			$(name).blur(checkName);
			$(telephone).blur(checkTelePhone);
			$(birthday).blur(checkBirthDay);
			$(check_code_info).blur(checkCode);
			//清除错误消息
			$(registerForm).click(()=>$(errorMsg).html('').css("color", ""))
		})
	</script>
	<body>
	<!--引入头部-->
	<div id="header"></div>
        <!-- 头部 end -->
    	<div class="rg_layout">
    		<div class="rg_form clearfix">
    			<div class="rg_form_left">
    				<p>新用户注册</p>
    				<p>USER REGISTER</p>
    			</div>
    			<div class="rg_form_center">
					<div id="errorMsg"></div>
					<!--注册表单-->
    				<form id="registerForm" action="user">
						<!--提交处理请求的标识符-->
						<input type="hidden" name="action" value="register">
    					<table style="margin-top: 25px;">
    						<tr>
    							<td class="td_left">
    								<label for="username">用户名</label>
    							</td>
    							<td class="td_right">
    								<input type="text" id="username" name="username" placeholder="请输入账号">
    							</td>
    						</tr>
    						<tr>
    							<td class="td_left">
    								<label for="password">密码</label>
    							</td>
    							<td class="td_right">
    								<input type="text" id="password" name="password" placeholder="请输入密码">
    							</td>
    						</tr>
							<tr>
								<td class="td_left">
									<label for="password">确认密码</label>
								</td>
								<td class="td_right">
									<input type="text" id="notarizepassword"  placeholder="请输入密码">
								</td>
							</tr>
    						<tr>
    							<td class="td_left">
    								<label for="email">Email</label>
    							</td>
    							<td class="td_right">
    								<input type="text" id="email" name="email" placeholder="请输入Email">
    							</td>
    						</tr>
    						<tr>
    							<td class="td_left">
    								<label for="name">姓名</label>
    							</td>
    							<td class="td_right">
    								<input type="text" id="name" name="name" placeholder="请输入真实姓名">
    							</td>
    						</tr>
    						<tr>
    							<td class="td_left">
    								<label for="telephone">手机号</label>
    							</td>
    							<td class="td_right">
    								<input type="text" id="telephone" name="telephone" placeholder="请输入您的手机号">
    							</td>
    						</tr>
    						<tr>
    							<td class="td_left">
    								<label for="sex">性别</label>
    							</td>
    							<td class="td_right gender">
    								<input type="radio" id="sex" name="sex" value="男" checked> 男
    								<input type="radio" name="sex" value="女"> 女
    							</td>
    						</tr>
    						<tr>
    							<td class="td_left">
    								<label for="birthday">出生日期</label>
    							</td>
    							<td class="td_right">
    								<input type="date" id="birthday" name="birthday" placeholder="年/月/日">
    							</td>
    						</tr>
    						<tr>
    							<td class="td_left">
    								<label for="check">验证码</label>
    							</td>
    							<td class="td_right check">
    								<input type="text" id="check" name="check" class="check">
    								<img src="checkCode" height="32px" alt="" onclick="changeCheckCode(this)">
									<script type="text/javascript">
										//图片点击事件
										function changeCheckCode(img) {
											img.src="checkCode?"+new Date().getTime();
                                        }
									</script>
    							</td>
    						</tr>
    						<tr>
    							<td class="td_left"> 
    							</td>
    							<td class="td_right check"> 
    								<input type="submit" class="submit" value="注册">
									<span id="msg" style="color: red;"></span>
    							</td>
    						</tr>
    					</table>
    				</form>
    			</div>
    			<div class="rg_form_right">
    				<p>
    					已有账号?
    					<a href="#">立即登录</a>
    				</p>
    			</div>
    		</div>
    	</div>
        <!--引入尾部-->
    	<div id="footer"></div>
		<!--导入布局js,共享header和footer-->
		<script type="text/javascript" src="js/include.js"></script>
    	
    </body>
</html>

注册成功页面

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>注册</title>
        <link rel="stylesheet" type="text/css" href="css/common.css">
        <link rel="stylesheet" href="css/register.css">
		<!--导入jquery-->
		<script src="js/jquery-3.3.1.js"></script>
    </head>
    <body>
    <!--引入头部-->
    <div id="header"></div>
        <!-- 头部 end -->
    	<div style="text-align:center;red:yellow;font-weight:bold;height:150px;padding-top:100px;font-size:30px;">
    		<h4>恭喜,注册成功!请登录您的注册邮箱进行激活您的账号,激活后才能登录。</h4>
    	</div>
        <!--引入尾部-->
    	<div id="footer"></div>
    <!--导入布局js,共享header和footer-->
    <script type="text/javascript" src="js/include.js"></script>
    </body>
</html>


后台
后台代码实现

编写RegistUserServlet

servlet

package cn.itcast.travel.web.servlet;

import cn.itcast.travel.domain.ResultInfo;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.UserService;
import cn.itcast.travel.service.impl.UserServiceImpl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.BeanUtils;


import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.Map;

@WebServlet(name = "registerUserServlet", value = "/registerUserServlet")
public class RegisterUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //验证校验
        String check = request.getParameter("check");
        //从session中获取验证码
        HttpSession session = request.getSession();
        String checkcode_session = (String)session.getAttribute("CHECKCODE_SERVER");
        session.removeAttribute("CHECKCODE_SERVER");
        if (checkcode_session == null || !checkcode_session.equalsIgnoreCase(check)) {
            ResultInfo info = new ResultInfo();
            info.setFlag(false);
            info.setErrorMsg("验证码错误");
            jsonWrite(request,response,info);
            return;
        }
        //调用注册用户接口
        register(request,response);
    }
    //注册用户
    public void register(HttpServletRequest request,HttpServletResponse response) throws IOException {
        //        获取数据
        Map<String, String[]> map = request.getParameterMap();
//        封装对象
        User user = new User();
        try {
            BeanUtils.populate(user, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        调用service完成注册
        UserService service = new UserServiceImpl();
        boolean flag = service.regist(user);
        ResultInfo info = new ResultInfo();
        if(flag){
            info.setFlag(true);
        }else {
            info.setFlag(false);
            info.setErrorMsg("注册失败");
        }
//        //将info对象序列化为json
        jsonWrite(request,response,info);
    }
    //对象序列化为json 并写回客户端
    public void jsonWrite(HttpServletRequest request,HttpServletResponse response ,ResultInfo info) throws IOException {
        //将info对象序列化为json
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(info);

        //将json数据写回客户端
//        设置content-type
        response.setContentType("application/json;charset=utf-8");
//        response.getWriter().write(json);
        response.getOutputStream().write(json.getBytes());
    }
}

servlet实现类

编写UserService以及UserServiceImpl

package cn.itcast.travel.service.impl;

import cn.itcast.travel.dao.UserDao;
import cn.itcast.travel.dao.impl.UserDaoImpl;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.UserService;
import cn.itcast.travel.util.MailUtils;
import cn.itcast.travel.util.UuidUtil;

public class UserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();
    /**
     * 注册用户
     * @param user
     * @return
     */
    @Override
    public boolean regist(User user) {
        //根据用户名查询用户对象
        User u = userDao.findByUsername(user.getUsername());
        //判断u是否为空
        if (u!= null) {
            //用户名存在,注册失败
            return false;
        }
        //置激活码,唯一字符串
        user.setCode(UuidUtil.getUuid());
        System.out.println(user.getCode());
        user.setStatus("N");
        //保存注册信息
        userDao.save(user);
        //激活邮件发送,邮件正文
        String content="<a href='http://localhost/travel/activeUserServlet?code="+user.getCode()+"'>点击激活码,完成激活</a>";
        MailUtils.sendMail(user.getEmail(),content,"激活邮件");
        System.out.println("发送成功");
        return true;
    }

    @Override
    public boolean active(String code) {
        //1.根据激活码查询用户对象
        User user = userDao.findByCode(code);
        if (user !=null) {
            //2.调用dao的修改激活状态的方法
            userDao.updateStatus(user);
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public User login(User user) {
        return userDao.findByUsernameAndPassword(user.getUsername(), user.getPassword());
    }
}

dao实现类

编写UserDao以及UserDaoImpl

package cn.itcast.travel.dao.impl;

import cn.itcast.travel.dao.UserDao;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

public class UserDaoImpl implements UserDao {
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    @Override
    public User findByUsername(String username) {
        User user = null;
        try {
            String sql = "select * from tab_user where username =?";
            user = template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class), username);
        } catch (Exception e) {
        }
        return user;
    }
    @Override
    public void save(User user) {
        String sql = "insert into tab_user(username,password,name,birthday,sex,telephone,email,status,code) values(?,?,?,?,?,?,?,?,?)";
        int update = template.update(sql, user.getUsername(),
                user.getPassword(),
                user.getName(),
                user.getBirthday(),
                user.getSex(),
                user.getTelephone(),
                user.getEmail(),
                user.getStatus(),
                user.getCode()
        );
    }

    @Override
    public User findByCode(String code) {
        User user = null;
        try {
            String sql = "select * from tab_user where code =?";
            user = template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class), code);
//            String sql = "select * from tab_user where code =?";
//            user = template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class), code);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return user;
    }

    @Override
    public void updateStatus(User user) {
        String sql = "update tab_user set status ='Y' where uid =?";
        template.update(sql, user.getUid());
    }

    @Override
    public User findByUsernameAndPassword(String username, String password) {
        User user = null;
        try {
            String sql = "select * from tab_user where username=? and password=?";
            user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password);
        } catch (Exception e) {

        }

        return user;
    }
}

邮件激活

为什么要进行邮件激活?为了保证用户填写的邮箱是正确的。将来可以推广一些宣传信息,到用户邮箱中。

发送邮件

  1. 申请邮箱
  2. 开启授权码
  3. 在MailUtils中设置自己的邮箱账号和密码(授权码)

 邮件工具类:MailUtils,调用其中sendMail方法可以完成邮件发送

用户点击邮件激活

经过分析,发现,用户激活其实就是修改用户表中的status为‘Y’

 分析

 发送邮件代码:

 修改保存Dao代码,加上存储status和code 的代码逻辑

 激活代码实现:

ActiveUserServlet

package cn.itcast.travel.web.servlet;

import cn.itcast.travel.service.impl.UserServiceImpl;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;


@WebServlet(name = "activeUserServlet", value = "/activeUserServlet")
public class ActiveUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取激活码
        String code = request.getParameter("code");
        if (code != null){
            //2.调用service完成激活
            UserServiceImpl service = new UserServiceImpl();
            boolean flag =  service.active(code);

            //3.判断标记
            String msg = flag ?"激活成功,请<a href='login.html'>登录</a>":"激活失败,请联系管理员";
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write(msg);
        }
    }
}

登录

分析

代码实现

前台代码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>旅游网-登录</title>  
    <link rel="stylesheet" type="text/css" href="css/common.css">
    <link rel="stylesheet" type="text/css" href="css/login.css">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
      <!--导入angularJS文件-->
    <script src="js/angular.min.js"></script>
	<!--导入jquery-->
	<script src="js/jquery-3.3.1.js"></script>
	<script>
		const btn_sub = "#btn_sub";
		const loginForm = "#loginForm";
		const errorMsg = "#errorMsg";
		$(()=>{
			$(btn_sub).click(function(){
				$.post("loginServlet",$(loginForm).serialize(),function (data){
					data.flag
							?location.href ="index.html"
							:$(errorMsg).html(data.errorMsg);
				})
			})
		})
	</script>
</head>

<body>
<!--引入头部-->
<div id="header"></div>
    <!-- 头部 end -->
    <section id="login_wrap">
        <div class="fullscreen-bg" style="background: url(images/login_bg.png);height: 532px;">
        	
        </div>
        <div class="login-box">
        	<div class="title">
        		<img src="images/login_logo.png" alt="">
        		<span>欢迎登录旅游账户</span>
        	</div>
        	<div class="login_inner">
				
				<!--登录错误提示消息-->
        		<div id="errorMsg" class="alert alert-danger" ></div>
				<form id="loginForm" action="" method="post" accept-charset="utf-8">
        			<input type="hidden" name="action" value="login"/>
					<input name="username" type="text" placeholder="请输入账号" autocomplete="off">
        			<input name="password" type="text" placeholder="请输入密码" autocomplete="off">
        			<div class="verify">
					<input name="check" type="text" placeholder="请输入验证码" autocomplete="off">
					<span><img src="checkCode" alt="" onclick="changeCheckCode(this)"></span>
					<script type="text/javascript">
						//图片点击事件
						function changeCheckCode(img) {
							img.src="checkCode?"+new Date().getTime();
						}
					</script>
			</div>
			<div class="submit_btn">
        				<button type="button" id="btn_sub">登录</button>
        				<div class="auto_login">
        					<input type="checkbox" name="" class="checkbox">
        					<span>自动登录</span>
        				</div>        				
        			</div>        			       		
        		</form>
        		<div class="reg">没有账户?<a href="javascript:;">立即注册</a></div>
        	</div>
        </div>
    </section>
    <!--引入尾部-->
    <div id="footer"></div>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="js/jquery-1.11.0.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
    <!--导入布局js,共享header和footer-->
    <script type="text/javascript" src="js/include.js"></script>
</body>

</html>

后台代码
LoginServlet

package cn.itcast.travel.web.servlet;

import cn.itcast.travel.domain.ResultInfo;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.impl.UserServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet(name = "loginServlet", value = "/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取用户名和密码数据
        Map<String, String[]> map = request.getParameterMap();
        //2.封装User对象
        User user = new User();
        try {
            BeanUtils.populate(user, map);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        //3.调用Service查询
        UserServiceImpl service = new UserServiceImpl();
        User u = service.login(user);
        ResultInfo info = new ResultInfo();
        //4.判断用户对象是否为null
        if(u==null) {
            //用户名密码或错误
            info.setResultInfo(info,false, null, "用户名密码或错误");
        }
        //5.判断用户是否激活
        if (u!=null && "Y".equals(u.getStatus())){
            info.setResultInfo(info,false, null, "您尚未激活,请激活");
        }
        //6.判断登录成功
        if(u!=null && "Y".equals(u.getStatus())){
            request.getSession().setAttribute("user",u);
            info.setFlag(true);
        }
        //响应数据
        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=UTF-8");
        mapper.writeValue(response.getOutputStream(),info);
    }

}

index页面中用户姓名的提示信息功能

效果:

 header.html代码

<!-- 头部 start -->
<script>
    const span_username = "#span_username";
    const login = "#login";
    $(()=>{
        $.get("findUserServlet",{},function (data){
            let msg = "欢迎回来:"+data.name;
            $(span_username).html(msg)
            $(login).css("display","none")
        })
    })
</script>
    <header id="header">
        <div class="top_banner">
            <img src="images/top_banner.jpg" alt="">
        </div>
        <div class="shortcut">
            <!-- 未登录状态  -->
            <div class="login_out" id="login">
                <a href="login.html">登录</a>
                <a href="register.html">注册</a>
            </div>
            <!-- 登录状态  -->
            <div class="login">
            	
                <span id="span_username">您尚未登陆</span>
                <a href="myfavorite.html" class="collection">我的收藏</a>
                <a href="javascript:location.href ='exitServlet';">退出</a>
            </div>
        </div>
        <div class="header_wrap">
            <div class="topbar">
                <div class="logo">
                    <a href="/"><img src="images/logo.jpg" alt=""></a>
                </div>
                <div class="search">
                    <input name="" type="text" placeholder="请输入路线名称" class="search_input" autocomplete="off">
                    <a href="javascript:;" class="search-button">搜索</a>
                </div>
                <div class="hottel">
                    <div class="hot_pic">
                        <img src="images/hot_tel.jpg" alt="">
                    </div>
                    <div class="hot_tel">
                        <p class="hot_time">客服热线(9:00-6:00)</p>
                        <p class="hot_num">400-618-9090</p>
                    </div>
                </div>
            </div>
        </div>
    </header>
    <!-- 头部 end -->
     <!-- 首页导航 -->
    <div class="navitem">
        <ul class="nav">
            <li class="nav-active"><a href="index.html">首页</a></li>
            <li><a href="route_list.html">门票</a></li>
            <li><a href="route_list.html">酒店</a></li>
            <li><a href="route_list.html">香港车票</a></li>
            <li><a href="route_list.html">出境游</a></li>
            <li><a href="route_list.html">国内游</a></li>
            <li><a href="route_list.html">港澳游</a></li>
            <li><a href="route_list.html">抱团定制</a></li>
            <li><a href="route_list.html">全球自由行</a></li>
            <li><a href="favoriterank.html">收藏排行榜</a></li>
        </ul>
    </div>
    

Servlet代码

package cn.itcast.travel.web.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "findUserServlet", value = "/findUserServlet")
public class FindUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从session中获取登录用户
        Object user = request.getSession().getAttribute("user");
        //将user写回客户端
        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=UTF-8");
        mapper.writeValue(response.getOutputStream(),user);
    }
}

退出

什么叫做登录了?session中有user对象。

实现步骤:

      1. 访问servlet,将session销毁
      2. 跳转到登录页面

代码实现:

Header.html

见上。
Servlet:

package cn.itcast.travel.web.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "exitServlet", value = "/exitServlet")
public class ExitServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().invalidate();
        response.sendRedirect(request.getContextPath()+"/login.html");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【c语言】数据结构-顺序表

主页&#xff1a;114514的代码大冒险 qq:2188956112&#xff08;欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ &#xff09; Gitee&#xff1a;庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、顺序表是什么&#xff1f; 二、项目功能的逐一实现&#xff08;基本&a…

Python-Flask-2023.1.22

1、WSGIweb server gateway interface一个框架定义的简单通用的接口Web服务器网关接口&#xff08;Python Web Server Gateway Interface&#xff0c;缩写为WSGI&#xff09;是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。flask框架内有默认的…

手写vue及源码解析一 rollup环境的搭建

开篇 都手写源码了&#xff0c;那就顺便分析一下源码吧。 rollup环境的搭建 作为了解就行。需要使用rollup来编译我们自己手写的vue代码。 需要安装rollup,rollup的babel插件&#xff0c;以及babel核心和babel预设&#xff08;可以理解为初始化模板&#xff09;。 mkdir vu…

Java变量定义时候的注意事项

常量定义的基本注意事项 在JAVA语言中&#xff0c;主要利用final关键字&#xff0c;&#xff08;在Java类中灵活使用static关键字&#xff09;来定义常量。 当常量被设定后&#xff0c;一般情况下就不允许在进行更改了&#xff0c;如可以利用以下的形式来定义常量&#xff1a;…

仿写Dubbo-Java Socket

概念 socket 被翻译为“套接字”&#xff0c;socket是计算机之间进行通信的一种方式。通过socket可以实现端(端口)到端通信。Java的java.net包中提供了进行socket通信的类。主要使用ServerSocket和Socket类实现通信。 ServerSocket 服务端应用使用java.net.ServerSocket类来获取…

Node.js 操作MongoDB (Mongoose) 数据库

在讲Node.js通过使用mongoose模块来操作MongoDB数据库之前首先是关于MongoDB数据库的安装和MongoDB服务以及对MongoDB命令行的操作和可视化工具MongoDBCompass的一个基本使用&#xff1b;那么在这里已经准备好了关于MongoDB数据库的内容了&#xff1a; MongoDB数据库安装详细 &…

学习shell与shell编程

Linux配置文件都是以ASCII的纯文本形式存在。 为什么学习vi 1)UnixLike系统都会内置vi文本编辑器&#xff0c;其他的文本编辑器则不一定存在 2)许多软件的编辑接口都会主动调用vi 3)vi具有程序编辑的能力&#xff0c;可以主动以字体颜色辨别语法的正确性 4)程序简单&#…

06-jquery函数

2.6函数 .6.1第一组函数 1 val():操作dom函数的value值 val()&#xff1a;没有参数&#xff0c;获取dom数组中第一个dom对象的value值。 val(参数)&#xff1a;有参数&#xff0c;给dom数组中所有dom对象的value属性赋值。 2 text()&#xff1a;操作标签文本内容&#xff0c;…

springCloud集成elk+filebeat+kafka+zipkin实现多个服务日志链路追踪聚合到es

一、目的 如今2023了&#xff0c;大多数javaweb架构都是springboot微服务&#xff0c;一个前端功能请求后台可能是多个不同的服务共同协做完成的。例如用户下单功能&#xff0c;js转发到后台网关gateway服务&#xff0c;然后到鉴权spring-sercurity服务&#xff0c;然后到业务…

【实操案例十一】使用try-except手动捕获异常 实例代码及运行效果图!

任务一&#xff1a; 编写程序输入学员成绩 异常捕获忘了的同学&#xff0c;可以参考这个&#xff1a;Bug的常见类型及异常处理机制 # 任务一&#xff1a; 编写程序输入学员成绩iint(input(请输入学员成绩&#xff1a;)) if 0<i<100:print(i) else:raise Exception(分数…

产品设计-基础控件-信息输入控件

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 产品设计-基础控件-信息输入控件1.1.文本框一、1.1.11.1.2、占位符文本1.1.3 输入框1.1.4 帮助文本1.1.5 初始默认值1.1.6 输入文本1.1.7 跟踪图标1.1.8 格式化标记1.2 单选按…

java枚举类2023028

一个类的对象是有限而且固定的&#xff0c;比如季节类&#xff0c; 它只有4个对象&#xff1b;再比如行星类&#xff0c;目前只有8个对象。这种实例有限而且固定的类&#xff0c;在Java里被称为枚举类。在早期代码中&#xff0c;可能会直接使用简单的静态常量来表示枚&#xff…

设计模式 - 六大设计原则之OCP(开闭原则)

文章目录概述Case接口定义接口实现Bad ImplBetter Impl概述 Open-Close Principle 在面向对象编程领域中&#xff0c;开闭原则规定软件中的类、对象、模块和函数对扩展应该是开放的&#xff0c;但对修改是封闭的。 这意味着 应该用抽象定义结构&#xff0c;用具体实现扩展细节…

使用 AJAX+JSON 实现用户查询/添加功能

实现用户查询/添加功能1. 查询功能准备selectAllServlet&#xff1a;brand.html&#xff1a;2. 添加功能addBrand.html&#xff1a;表单&#xff1a;<script&#xff1a;addServlet&#xff1a;1. 查询功能 需求&#xff1a;在onload&#xff08;页面加载完成&#xff09;事…

SSM项目实战【从 0 到 1】:个人博客

文章目录前言一、项目简介二、项目技术栈三、准备工作1、Spring Boot 项目创建2、mybatis 配置3、数据库创建四、基本框架搭建1、实体层&#xff08;model&#xff09;2、控制器层&#xff08;controller&#xff09;3、服务层&#xff08;service&#xff09;4、持久层&#x…

Liunx相关服务无法启动,带你一步一步找出问题和解决问题

liunx服务无法开启的原因有各种各样&#xff0c;首先我们需要找到我们究竟是为什么不能能够开启这个服务&#xff0c;这里我们先要去考虑到的一个非常重要的问题就是我们的防火墙有没有启动&#xff0c;防火墙有没有把我们的要开启相关服务的端口给封禁掉。这个是无论如何都要第…

学习记录668@项目管理之项目沟通管理和干系人管理

书上这部分的内容很无趣、很花里花哨、很杂乱&#xff0c;所以本文只摘取我认为比较有用和有意义的片段。 沟通方式 在发送方自认为已经掌握了足够的信息&#xff0c;有了自己的想法且不需要进一步听取多方意见时&#xff0c;往往选择控制力极强、参与程度最弱的“叙述方式”&a…

ES学习看这一篇文章就够了

第一章 ES简介 第1节 ES介绍 1 2 3 41、Elasticsearch是一个基于Lucene的搜索服务器 2、提供了一个分布式的全文搜索引擎,基于restful web接口 3、Elasticsearch是用Java语言开发的&#xff0c;基于Apache协议的开源项目&#xff0c;是目前最受欢迎的企业搜索引擎 4、Elastics…

机器学习(四):机器学习工作流程

文章目录 机器学习工作流程 一、什么是机器学习 二、机器学习工作流程 1、获取到的数据集介绍 2、数据基本处理 3、特征工程 4、机器学习 5、模型评估 机器学习工作流程 一、什么是机器学习 机器学习是从数据中自动分析获得模型&#xff0c;并利用模型对未知数据进行…

【程序环境和程序预处理】万字详文,忘记了,看这篇就对了

本章介绍一个test.c文件是如何生成一个test.exe文件。首先了解程序环境和程序预处理的大致流程&#xff0c;本章会分别介绍各个流程&#xff0c;但重点是翻译中的编译中的预编译阶段。 文章目录&#xff1a; 1.程序翻译环境和运行环境 1.1程序翻译中的的编译和链接 2.预编译…