JavaEE17_Web案例

文章目录

项目导入

点击按钮将项目导入
在这里插入图片描述
选择travel项目的pom.xml文件,点击ok,完成项目导入。需要等待一小会,项目初始化完成。
在这里插入图片描述

启动项目

1. 方式1

在这里插入图片描述

2. 方式2

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

技术选型

1. web层

1.1 为什么使用html而不使用jsp?

首先该项目是一个互联网项目,该项目是给普通的用户访问的,所以要追求速度快,而且要做到前后端分离,所以使用html作为视图,如果将来做一些后台管理系统,比如OA和财务管理系统是给内部人员使用的就可以使用jsp作为视图。

  • Servlet:前端控制器
  • html:视图
  • Filter:过滤器
  • BeanUtils:数据封装
  • Jackson:json序列化工具

2. service层

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

3. dao层

  • Mysql:数据库
  • Druid:数据库连接池
  • JdbcTemplate:jdbc的工具

创建数据库

创建数据库
CREATE DATABASE travel;
使用数据库
USE travel;
创建表
复制提供好的sql

工具类

1. JDBCUtils

/*
	1. 声明静态数据源成员变量
	2. 创建连接池对象
	3. 定义公有的得到数据源的方法
	4. 定义得到连接对象的方法
	5. 定义关闭资源的方法
 */
public class JDBCUtil {
   
	// 1.	声明静态数据源成员变量
	private static DataSource ds;

	// 2. 创建连接池对象
	static {
   
		// 加载配置文件中的数据
		InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties");
		Properties pp = new Properties();
		try {
   
			pp.load(is);
			// 创建连接池,使用配置文件中的参数
			ds = DruidDataSourceFactory.createDataSource(pp);
		} catch (IOException e) {
   
			e.printStackTrace();
		} catch (Exception e) {
   
			e.printStackTrace();
		}
	}

	// 3. 定义公有的得到数据源的方法
	public static DataSource getDataSource() {
   
		return ds;
	}

	// 4. 定义得到连接对象的方法
	public static Connection getConnection() throws SQLException {
   
		return ds.getConnection();
	}

	// 5.定义关闭资源的方法
	public static void close(Connection conn, Statement stmt, ResultSet rs) {
   
		if (rs != null) {
   
			try {
   
				rs.close();
			} catch (SQLException e) {
   }
		}

		if (stmt != null) {
   
			try {
   
				stmt.close();
			} catch (SQLException e) {
   }
		}

		if (conn != null) {
   
			try {
   
				conn.close();
			} catch (SQLException e) {
   }
		}
	}

	// 6.重载关闭方法
	public static void close(Connection conn, Statement stmt) {
   
		close(conn, stmt, null);
	}
}

2. JedisUtil

/**
 * Jedis工具类
 */
public final class JedisUtil {
   
    private static JedisPool jedisPool;
    static {
   
        //读取配置文件
        InputStream is = JedisPool.class.getClassLoader().getResourceAsStream("jedis.properties");
        //创建Properties对象
        Properties pro = new Properties();
        //关联文件
        try {
   
            pro.load(is);
        } catch (IOException e) {
   
            e.printStackTrace();
        }
        //获取数据,设置到JedisPoolConfig中
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));

        //初始化JedisPool
        jedisPool = new JedisPool(config, pro.getProperty("host"), Integer.parseInt(pro.getProperty("port")));
    }

    /**
     * 获取连接方法
     */
    public static Jedis getJedis() {
   
        return jedisPool.getResource();
    }

    /**
     * 关闭Jedis
     */
    public static void close(Jedis jedis) {
   
        if (jedis != null) {
   
            jedis.close();
        }
    }
}

3. MailUtil

/**
 * 发邮件工具类
 */
public final class MailUtil {
   
    private static final String USER = "1290089493@qq.com"; // 发件人称号,同邮箱地址
    private static final String PASSWORD ="jaitpzdgkrofjgfb"; // 如果是qq邮箱可以使户端授权码,或者登录密码

    /**
     *
     * @param to 收件人邮箱
     * @param text 邮件正文
     * @param title 标题
     */
    /* 发送验证信息的邮件 */
    public static boolean sendMail(String to, String text, String title){
   
        try {
   
            final Properties props = new Properties();
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.host", "smtp.qq.com");

            // 发件人的账号
            props.put("mail.user", USER);
            //发件人的密码
            props.put("mail.password", PASSWORD);

            // 构建授权信息,用于进行SMTP进行身份验证
            Authenticator authenticator = new Authenticator() {
   
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
   
                    // 用户名、密码
                    String userName = props.getProperty("mail.user");
                    String password = props.getProperty("mail.password");
                    return new PasswordAuthentication(userName, password);
                }
            };
            // 使用环境属性和授权信息,创建邮件会话
            Session mailSession = Session.getInstance(props, authenticator);
            // 创建邮件消息
            MimeMessage message = new MimeMessage(mailSession);
            // 设置发件人
            String username = props.getProperty("mail.user");
            InternetAddress form = new InternetAddress(username);
            message.setFrom(form);

            // 设置收件人
            InternetAddress toAddress = new InternetAddress(to);
            message.setRecipient(Message.RecipientType.TO, toAddress);

            // 设置邮件标题
            message.setSubject(title);

            // 设置邮件的内容体
            message.setContent(text, "text/html;charset=UTF-8");
            // 发送邮件
            Transport.send(message);
            return true;
        }catch (Exception e){
   
            e.printStackTrace();
        }
        return false;
    }

    public static void main(String[] args) throws Exception {
    // 做测试用
        MailUtils.sendMail("ginger_mr@163.com","你好,这是一封测试邮件,无需回复。","测试邮件");
        System.out.println("发送成功");
    }
}

4. Md5Util

/**
 * 写一个MD5算法,运行结果与MySQL的md5()函数相同
 * 将明文密码转成MD5密码
 * 123456->e10adc3949ba59abbe56e057f20f883e
 */
public final class Md5Util {
   
	private Md5Util(){
   }
	/**
	 * 将明文密码转成MD5密码 
	 */
	public static String encodeByMd5(String password) throws Exception{
   
		//Java中MessageDigest类封装了MD5和SHA算法,今天我们只要MD5算法
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		//调用MD5算法,即返回16个byte类型的值
		byte[] byteArray = md5.digest(password.getBytes());
		//注意:MessageDigest只能将String转成byte[],接下来的事情,由我们程序员来完成
		return byteArrayToHexString(byteArray);
	}
	/**
	 * 将byte[]转在16进制字符串 
	 */
	private static String byteArrayToHexString(byte[] byteArray) {
   
		StringBuffer sb = new StringBuffer();
		//遍历
		for(byte b : byteArray){
   //16次
			//取出每一个byte类型,进行转换
			String hex = byteToHexString(b);
			//将转换后的值放入StringBuffer中
			sb.append(hex);
		}
		return sb.toString();
	}
	/**
	 * 将byte转在16进制字符串 
	 */
	private static String byteToHexString(byte b) {
   //-31转成e1,10转成0a,。。。
		//将byte类型赋给int类型
		int n = b;
		//如果n是负数
		if(n < 0){
   
			//转正数
			//-31的16进制数,等价于求225的16进制数 
			n = 256 + n;
		}
		//商(14),数组的下标
		int d1 = n / 16;
		//余(1),数组的下标
		int d2 = n % 16;
		//通过下标取值
		return hex[d1] + hex[d2];
	}
	private static String[] hex = {
   "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
	/**
	 * 测试
	 */
	public static void main(String[] args) throws Exception{
   
		String password = "123456";
		String passwordMD5 = Md5Util.encodeByMd5(password);
		System.out.println(password);
		System.out.println(passwordMD5);
	}
}

5. UUIDUtil

/**
 * 产生UUID随机字符串工具类
 */
public final class UUIDUtil {
   
	private UuidUtil(){
   }
	public static String getUuid(){
   
		return UUID.randomUUID().toString().replace("-","");
	}
	/**
	 * 测试
	 */
	public static void main(String[] args) {
   
		System.out.println(UuidUtil.getUuid());
		System.out.println(UuidUtil.getUuid());
		System.out.println(UuidUtil.getUuid());
		System.out.println(UuidUtil.getUuid());
	}
}

6. druid.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///travel
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000

7. jedis.properties

host=127.0.0.1
port=6379
maxTotal=50
maxIdle=10

实体类

1. Category

/**
 * 分类实体类
 */
public class Category implements Serializable {
   
    private int cid;//分类id
    private String cname;//分类名称

    public Category() {
   
    }

    public Category(int cid, String cname) {
   
        this.cid = cid;
        this.cname = cname;
    }

    @Override
    public String toString() {
   
        return "Category{" +
                "cid=" + cid +
                ", cname='" + cname + '\'' +
                '}';
    }

    public int getCid() {
   
        return cid;
    }

    public void setCid(int cid) {
   
        this.cid = cid;
    }

    public String getCname() {
   
        return cname;
    }

    public void setCname(String cname) {
   
        this.cname = cname;
    }
}

2. Favorite

/**
 * 收藏实体类
 */
public class Favorite implements Serializable {
   
    private Route route;//旅游线路对象
    private String date;//收藏时间
    private User user;//所属用户

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

    /**
     * 有参构造方法
     * @param route
     * @param date
     * @param user
     */
    public Favorite(Route route, String date, User user) {
   
            this.route = route;
            this.date = date;
            this.user = user;
    }

    public Route getRoute() {
   
        return route;
    }

    public void setRoute(Route route) {
   
        this.route = route;
    }

    public String getDate() {
   
        return date;
    }

    public void setDate(String date) {
   
        this.date = date;
    }

    public User getUser() {
   
        return user;
    }

    public void setUser(User user) {
   
        this.user = user;
    }
}

3. PageBean

/**
 * 分页实体类
 */
public class PageBean<T> {
   
    private int currentPage;//当前页
    private int currentNumber;//当前页显示的条数
    private int totalCount;//总条数
    private int totalPage;//总页数
    private List<T> list;//每页显示的数据

    //添加一个线路名称
    private String rname;

    public String getRname() {
   
        return rname;
    }

    public void setRname(String rname) {
   
        this.rname = rname;
    }

    public int getCurrentPage() {
   
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
   
        this.currentPage = currentPage;
    }

    public int getCurrentNumber() {
   
        return currentNumber;
    }

    public void setCurrentNumber(int currentNumber) {
   
        this.currentNumber = currentNumber;
    }

    public int getTotalCount() {
   
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
   
        this.totalCount = totalCount;
    }

    public int getTotalPage() {
   
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
   
        this.totalPage = totalPage;
    }

    public List<T> getList() {
   
        return list;
    }

    public void setList(List<T> list) {
   
        this.list = list;
    }

    @Override
    public String toString() {
   
        return "PageBean{" +
                "currentPage=" + currentPage +
                ", currentNumber=" + currentNumber +
                ", totalCount=" + totalCount +
                ", totalPage=" + totalPage +
                ", list=" + list +
                '}';
    }
}

4. ResultInfo

/**
 * 用于封装后端返回前端数据对象
 */
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;
    }
}

5. Route

/**
 * 旅游线路商品实体类
 */
public class Route implements Serializable {
   

    private int rid;//线路id,必输
    private String rname;//线路名称,必输
    private double price;//价格,必输
    private String routeIntroduce;//线路介绍
    private String rflag;   //是否上架,必输,0代表没有上架,1代表是上架
    private String rdate;   //上架时间
    private String isThemeTour;//是否主题旅游,必输,0代表不是,1代表是
    private int count;//收藏数量
    private int cid;//所属分类,必输
    private String rimage;//缩略图
    private int sid;//所属商家
    private String sourceId;//抓取数据的来源id

    private Category category;//所属分类
    private Seller seller;//所属商家
    private List<RouteImg> routeImgList;//商品详情图片列表
    
    /**
     * 无参构造方法
     */
    public Route(){
   }

    /**
     * 有参构造方法
     * @param rid
     * @param rname
     * @param price
     * @param routeIntroduce
     * @param rflag
     * @param rdate
     * @param isThemeTour
     * @param count
     * @param cid
     * @param rimage
     * @param sid
     * @param sourceId
     */
    public Route(int rid, String rname, double price, String routeIntroduce, String rflag, String rdate, String isThemeTour, int count, int cid, String rimage, int sid, String sourceId) {
   
        this.rid = rid;
        this.rname = rname;
        this.price = price;
        this.routeIntroduce = routeIntroduce;
        this.rflag = rflag;
        this.rdate = rdate;
        this.isThemeTour = isThemeTour;
        this.count = count;
        this.cid = cid;
        this.rimage = rimage;
        this.sid = sid;
        this.sourceId = sourceId;
    }

    public List<RouteImg> getRouteImgList() {
   
        return routeImgList;
    }

    public void setRouteImgList(List<RouteImg> routeImgList) {
   
        this.routeImgList = routeImgList;
    }

    public Category getCategory() {
   
        return category;
    }

    public void setCategory(Category category) {
   
        this.category = category;
    }

    public Seller getSeller() {
   
        return seller;
    }

    public void setSeller(Seller seller) {
   
        this.seller = seller;
    }

    public String getSourceId() {
   
        return sourceId;
    }

    public void setSourceId(String sourceId) {
   
        this.sourceId = sourceId;
    }

    public int getRid() {
   
        return rid;
    }

    public void setRid(int rid) {
   
        this.rid = rid;
    }

    public String getRname() {
   
        return rname;
    }

    public void setRname(String rname) {
   
        this.rname = rname;
    }

    public double getPrice() {
   
        return price;
    }

    public void setPrice(double price) {
   
        this.price = price;
    }

    public String getRouteIntroduce() {
   
        return routeIntroduce;
    }

    public void setRouteIntroduce(String routeIntroduce) {
   
        this.routeIntroduce = routeIntroduce;
    }

    public String getRflag() {
   
        return rflag;
    }

    public void setRflag(String rflag) {
   
        this.rflag = rflag;
    }

    public String getRdate() {
   
        return rdate;
    }

    public void setRdate(String rdate) {
   
        this.rdate = rdate;
    }

    public String getIsThemeTour() {
   
        return isThemeTour;
    }

    public void setIsThemeTour(String isThemeTour) {
   
        this.isThemeTour = isThemeTour;
    }

    public int getCount() {
   
        return count;
    }

    public void setCount(int count) {
   
        this.count = count;
    }

    public int getCid() {
   
        return cid;
    }

    public void setCid(int cid) {
   
        this.cid = cid;
    }

    public String getRimage() {
   
        return rimage;
    }

    public void setRimage(String rimage) {
   
        this.rimage = rimage;
    }

    public int getSid() {
   
        return sid;
    }

    public void setSid(int sid) {
   
        this.sid = sid;
    }

    @Override
    public String toString() {
   
        return "Route{" +
                "rid=" + rid +
                ", rname='" + rname + '\'' +
                ", price=" + price +
                ", routeIntroduce='" + routeIntroduce + '\'' +
                ", rflag='" + rflag + '\'' +
                ", rdate='" + rdate + '\'' +
                ", isThemeTour='" + isThemeTour + '\'' +
                ", count=" + count +
                ", cid=" + cid +
                ", rimage='" + rimage + '\'' +
                ", sid=" + sid +
                ", sourceId='" + sourceId + '\'' +
                ", category=" + category +
                ", seller=" + seller +
                ", routeImgList=" + routeImgList +
                '}';
    }
}

6. RouteImg

/**
 * 旅游线路图片实体类
 */
public class RouteImg implements Serializable {
   
    private int rgid;//商品图片id
    private int rid;//旅游商品id
    private String bigPic;//详情商品大图
    private String smallPic;//详情商品小图

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

    /**
     * 有参构造方法
     * @param rgid
     * @param rid
     * @param bigPic
     * @param smallPic
     */
    public RouteImg(int rgid, int rid, String bigPic, String smallPic) {
   
        this.rgid = rgid;
        this.rid = rid;
        this.bigPic = bigPic;
        this.smallPic = smallPic;
    }

    public int getRgid() {
   
        return rgid;
    }

    public void setRgid(int rgid) {
   
        this.rgid = rgid;
    }

    public int getRid() {
   
        return rid;
    }

    public void setRid(int rid) {
   
        this.rid = rid;
    }

    public String getBigPic() {
   
        return bigPic;
    }

    public void setBigPic(String bigPic) {
   
        this.bigPic = bigPic;
    }

    public String getSmallPic() {
   
        return smallPic;
    }

    public void setSmallPic(String smallPic) {
   
        this.smallPic = smallPic;
    }
}

7. Seller

/**
 * 商家实体类
 */
public class Seller implements Serializable {
   
    private int sid;//商家id
    private String sname;//商家名称
    private String consphone;//商家电话
    private String address;//商家地址

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

    /**
     * 构造方法
     * @param sid
     * @param sname
     * @param consphone
     * @param address
     */
    public Seller(int sid, String sname, String consphone, String address) {
   
        this.sid = sid;
        this.sname = sname;
        this.consphone = consphone;
        this.address = address;
    }

    public int getSid() {
   
        return sid;
    }

    public void setSid(int sid) {
   
        this.sid = sid;
    }

    public String getSname() {
   
        return sname;
    }

    public void setSname(String sname) {
   
        this.sname = sname;
    }

    public String getConsphone() {
   
        return consphone;
    }

    public void setConsphone(String consphone) {
   
        this.consphone = consphone;
    }

    public String getAddress() {
   
        return address;
    }

    public void setAddress(String address) {
   
        this.address = address;
    }
}

8. User

/**
 * 用户实体类
 */
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;
    }
}

注册功能

1. 注册功能陌生点总结

将页面滚动到页面顶部。
window.scrollTo(0,0);

获取请求地址?后面的所有参数包括?。
location.search

获取表单中所有的请求参数和参数值,拼接成key=value形式的字符串不包括?$(this).serialize()

2. 页面效果

在这里插入图片描述

3. 前台代码实现

3.1 介绍引入头部和底部通用的html

在很多网站其实顶部和底部页面部分代码其实是不经常改变的,为了满足这个需求就把公共部分提取到两个html中,然后在使用异步请求去加载这两个html放到顶部和底部。

<!--导入布局js,共享header和footer-->
<script type="text/javascript" src="js/include.js"></script>

<!--引入头部-->
	<div id="header"></div>
	主体html代码
<!--引入尾部-->
    <div id="footer"></div>

include.js引入底部和头部html的jquery代码

$(function () {
   
    $.get("header.html",function (data) {
   
        $("#header").html(data);
    });
    $.get("footer.html",function (data) {
   
        $("#footer").html(data);
    });
});

3.2 register页面代码

<!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>
    //写一个页面加载事件
    $(function () {
   
        //提交表单
        $("#registerForm").submit(function () {
   
            //判断表单是否符合条件
       if (checkUsername && checkPasswrod && checkEmail && checkName && checkTelephone && checkBirthday && checkCode) {
   
                //如何就发送异步请求
                $.get("registerServlet", $(this).serialize(), function (data) {
   
                    if (data.flag) {
   
                        //{"flag":false,"data":null,"errorMsg":"注册失败,用户名已经存请重新输入!"}
                        //注册成功
                        alert("注册成功
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值