前言:
本项目使用Java开发的后端,前端html+css+JavaScript+Ajax;
接下来将会带大家一起一步一步从html的使用到javaweb后端的开发详细介绍一遍,不懂得随时提问,我都会回复。我在这里简单说一下这个javaweb项目的重要部分。这其实也是一个很基础的javaweb项目(也算是前后端分离的项目),开源给大家免费学习。
JavaWeb-商城Github开源项目地址:点击进入开源下载
原视频演示Demo地址:点击播放
好,废话不多说,进入今天的开发主主题。
项目截图:
好的,看过项目部分截图,接下来直接来说一下整个项目的开发吧:
1.userinfo数据表(如下图)
userinfo的代码:
DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo` (
`ID` int(100) NOT NULL AUTO_INCREMENT,
`nickname` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`phonenumber` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`email` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`code` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`sex` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`birthday` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`passwd` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Compact;
DROP TABLE IF EXISTS `shop`;
CREATE TABLE `shop` (
`ID` int(255) NOT NULL AUTO_INCREMENT,
`user` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`price` varchar(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`number` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`chima` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`color` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`img` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`maijia` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Compact;
由于是基础的demo所以没有在数据的约束性设计多做专研,只是简单地对数据库进行建表操作,这也是本项目的不足之处(更多的留给大家来发掘研究)直接运行sql文件即可。下面系统性讲述一下开发过程。
(1)前端登录界面实现:
前端登录核心是表单的提交地址,html中css只是渲染作用,js才是控制业务逻辑走向的核心,js才是实现前后端交互的核心内容。知道了这一点,我们还需要知道,js可以控制html的标签,包括属性,内容等,有了这些基础知识,那么进入下一个主题:上代码:
>
action填写你的servlet地址,这样就可以在目标地址的servlet中进行获取数据并且进行相应的判断:
String nickname=request.getParameter("nickname");
String pwd = request.getParameter("pwd");
JDBC yu = new JDBC();
HttpSession session =request.getSession();
session.setAttribute("nickname", nickname);
session.setAttribute("psswd",pwd);
try {
if(yu.inthetable("databasename","userinfo", "nickname", nickname, pwd)) {
//inthetable方法是我自己封装在jdbc中的方法,用来判断目标数据表书否存在已知信息
response.sendRedirect("store.html");
}else {
response.sendRedirect("dlsb.html");
}
} catch (Exception e) {
}
介绍一下JDBC的方法:(我看有的博客介绍是说可以将connection封装起来,我这里也是借鉴相同方法进行封装)
package com.sinsy.web.usersql;
/**
* author fntp 2020/05/02
*/
import javax.xml.transform.Result;
import java.sql.*;
import java.util.Arrays;
public class JDBC {
//实现使用JDBC连接数据库MySQL
private static String url = "jdbc:mysql://";
private static String ip = "127.0.0.1:";
private static int port = 3306;
private static String target_database = "/scx";
// MySQL配置时的用户名
private static String user = "root";
// Java连接MySQL配置时的密码
private static String password = "root";
public static String getMysql() {
// URL指向要访问的数据库名
String URL = url + ip + port + target_database;
//jdbc驱动名称
String driverName = "com.mysql.jdbc.Driver";
try {
// 加载驱动程序
Class.forName(driverName);
// 连续数据库
Connection connection = DriverManager.getConnection(url, user, password);
//通过连接获取statement
Statement statement = connection.createStatement();
System.out.println("鑫软提示:已经成功加载至MySQL,并且连接数据库scx成功!");
// 利用statement输入命令获取数据
String use_sql = "use scx;";
ResultSet use_result = statement.executeQuery(use_sql);
String show_sql = "show tables";
ResultSet show_result = statement.executeQuery(show_sql);
// desc格式化输出数据表的字段结构,然后对目标字段进行数据采集,并且按照格式化输出!
// String desc_table_sql_1 = "desc userinfo";
// ResultSet desc_result_1 = statement.executeQuery(desc_table_sql_1);
// String select_sql_getdates = "select * from userinfo";
// 获取命令执行的结果:
// 将选择出来的数据进行格式化输出,目的是为了区分数据库的个数
int tables_bunber = 0;
while (show_result.next()) {
tables_bunber += 1;
System.out.println("第" + tables_bunber + "个数据表是:" + show_result.getString(1));
}
// while(desc_result_1.next()){
// System.out.println("目标数据表的字段是:"+desc_result_1.getString("Field")+
// desc_result_1.getString("Type")+desc_result_1.getString("Null"));
// }
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return null;
}
// public static String gettable(){
第一步:获取目标数据库的数据表
// String sql_gettable= "show tables";
// return sql_gettable;
// }
public static void main(String[] args) throws SQLException, ClassNotFoundException {
// 测试案例
// gettables();
// 测试案例使用的是静态方法
// insertintable("孙程鑫","99love");
// 将方法改为静态方法就可以执行,但是非静态方法是无法执行的
// 静态方法不可以在申明对象的时候进行调用
// System.out.println(tablelength());
}
// 向目标数据表插入数据(1)测试方法
public static void insertintable(String username,String userpasswd) throws SQLException, ClassNotFoundException {
Statement statement = getConnection().createStatement();
// 首先获取初始化的表的自增长字段的长度
// 如果是内部调用静态的可以的
int initlength = tablelength();
// 然后进行插入操作,
PreparedStatement pare_sql;
pare_sql = getConnection().prepareStatement("insert into userinfo(username,userpasswd) "
+ "values(?,?)");
pare_sql.setString(1, username);
pare_sql.setString(2, userpasswd);
// String insert_sql = "insert into userinfo(username,userpasswd) values("+username+","+userpasswd+")";
// ResultSet resultSet = statement.executeQuery(insert_sql);
// 判断是否插入成功!
pare_sql.executeUpdate();
int endlenth = tablelength();
if (initlength < endlenth) {
System.out.println("恭喜您!已经成功插入数据!");
} else {
System.out.println("很抱歉,插入失败!");
}
}
// 将数据注入sql指定数据表(2)使用方法
public void InsertInToTable(String database,String tablename,String nickname,String phonenumber,
String email,String code,String sex,String birthday,String passwd) throws SQLException, ClassNotFoundException {
Statement statement = GetConnection(database).createStatement();
// 首先获取初始化的表的自增长字段的长度
// 如果是内部调用静态的可以的
int initlength = tablelength();
// 然后进行插入操作,
PreparedStatement pare_sql;
pare_sql = getConnection().prepareStatement("insert into "+tablename+"(nickname,phonenumber,email,code,sex,birthday,passwd) "
+ "values(?,?,?,?,?,?,?)");
pare_sql.setString(1, nickname);
pare_sql.setString(2, phonenumber);
pare_sql.setString(3, email);
pare_sql.setString(4, code);
pare_sql.setString(5, sex);
pare_sql.setString(6, birthday);
pare_sql.setString(7, passwd);
// String insert_sql = "insert into userinfo(username,userpasswd) values("+username+","+userpasswd+")";
// ResultSet resultSet = statement.executeQuery(insert_sql);
// 判断是否插入成功!
pare_sql.executeUpdate();
int endlenth = tablelength();
if (initlength < endlenth) {
System.out.println("恭喜您!已经成功插入数据!");
} else {
System.out.println("很抱歉,插入失败!");
}
}
// 插数据进入sql保存商品信息
public void insertIntoShop(String database,String tablename,String user,String name,String price,
String number,String chima,String color,String img,String maijia) throws ClassNotFoundException, SQLException {
Statement statement = GetConnection(database).createStatement();
PreparedStatement pare_sql;
pare_sql = getConnection().prepareStatement("insert into "+tablename+"(user,name,price,number,chima,color,img,maijia) "
+ "values(?,?,?,?,?,?,?,?)");
pare_sql.setString(1, user);
pare_sql.setString(2, name);
pare_sql.setString(3, price);
pare_sql.setString(4, number);
pare_sql.setString(5, chima);
pare_sql.setString(6, color);
pare_sql.setString(7,img);
pare_sql.setString(8, maijia);
pare_sql.executeUpdate();
}
// 获取table
public static void gettables() throws SQLException, ClassNotFoundException {
Statement statement=getConnection().createStatement();
String select_tables = "select * from userinfo";
ResultSet resultSet = statement.executeQuery(select_tables);
while(resultSet.next()){
System.out.println(resultSet.getString("ID")+resultSet.getString("username")+"--"+resultSet.getString("userpasswd"));
}
}
// 判断目标数据表是否为空
public static boolean tableisnull() throws SQLException, ClassNotFoundException {
Statement statement=getConnection().createStatement();
String select_tables = "select * from userinfo";
ResultSet resultSet = statement.executeQuery(select_tables);
if(resultSet.next())
return true;
return false;
}
// 求目标数组的数据量(换算为长度按照ID取值)
public static int tablelength() throws SQLException, ClassNotFoundException {
Statement statement=getConnection().createStatement();
String select_tables = "select * from userinfo";
ResultSet resultSet = statement.executeQuery(select_tables);
String length[]=new String[100];
int a=0;
while(resultSet.next()){
length[a]=(resultSet.getString("ID"));
a+=1;
}
int c=0;
for(int b=0;b<length.length;b++){
if (length[b]!=null)
c++;
}
return c;
}
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
// String url = "jdbc:mysql://localhost:3306/zhiyou_apartment?useUnicode=true&characterEncoding=utf-8&useSSL=false";
String url = "jdbc:mysql://localhost:3306/scx";
String user = "root";
String password = "root";
Connection conn = null;
try {
conn= DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
//实战使用:
public Connection GetConnection(String database) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
// String url = "jdbc:mysql://localhost:3306/zhiyou_apartment?useUnicode=true&characterEncoding=utf-8&useSSL=false";
String url = "jdbc:mysql://localhost:3306/"+database;
String user = "root";
String password = "root";
Connection conn = null;
try {
conn= DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
//TODO:讲目标数据进行验证操作:
public boolean inthetable(String database,String table,String key,String value,String pwd) throws ClassNotFoundException, SQLException {
PreparedStatement pstmt = null;
ResultSet rs =null;
String sql= "select * from "+table+" where "+key+"="+"\""+value+"\""+" and passwd="+"\""+pwd+"\""+"; ";
if(table!=null&&value!=null&&pwd!=null) {
pstmt = GetConnection(database).prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.next()) {
return true;
}
}
return false;
}
}
(2)登陆失败自动跳转至注册页面
这块就没啥好讲的了,就是基础的js控制层(源代码都在github那个文件夹里面大家参考一下,里面有说明)
(3)注册成功验证完成自动插入数据库
来看演示:
核心代码:
package com.sinsy.web.sendEmail;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
public class Html_send {
String Code=null;
public static void sendMessage(String smtpHost,
String from, String to,
String subject, String messageText)
throws MessagingException,java.io.UnsupportedEncodingException {
// Step 1: 配置邮件会话session
System.out.println("Configuring mail session for: " + smtpHost);
java.util.Properties props = new java.util.Properties();
props.setProperty("mail.smtp.auth", "true");//指定是否需要SMTP验证
props.setProperty("mail.smtp.host", smtpHost);//指定SMTP服务器
props.put("mail.transport.protocol", "smtp");
Session mailSession = Session.getDefaultInstance(props);
mailSession.setDebug(true);//是否在控制台显示debug信息
// Step 2: 构建消息
System.out.println("Constructing message - from=" + from + " to=" + to);
InternetAddress fromAddress = new InternetAddress(from);
InternetAddress toAddress = new InternetAddress(to);
MimeMessage testMessage = new MimeMessage(mailSession);
testMessage.setFrom(fromAddress);
testMessage.addRecipient(javax.mail.Message.RecipientType.TO, toAddress);
testMessage.setSentDate(new java.util.Date());
testMessage.setSubject(MimeUtility.encodeText(subject,"gb2312","B"));
testMessage.setContent(messageText, "text/html;charset=gb2312");
System.out.println("Message constructed");
// Step 3: 开始发送HTML邮件
Transport transport = mailSession.getTransport("smtp");
transport.connect(smtpHost, "email地址", "授权码");
transport.sendMessage(testMessage, testMessage.getAllRecipients());
transport.close();
System.out.println("Message sent!");
}
// public static void main(String[] args) {
public Html_send(String emailaddress) {
String path ="C:\\Users\\Administrator\\Desktop\\鑫软工作室2020版工作室网站\\images\\logo.png";
String smtpHost = "smtp.163.com";
String from = "[email protected]";
// String to = "[email protected]";
String to = emailaddress;
String subject = "鑫软科技";
//subject javamail自动转码
Verification demo =new Verification();
Code=demo.getcode(demo.random_number(),demo.random_char());
StringBuffer theMessage = new StringBuffer();
theMessage.append("鑫软科技
");
theMessage.append("鑫软注册验证码
您的验证码是:"+Code+"!
本");
theMessage.append("验证码仅十分钟有效!请您尽快登陆您的注册页面,输如您上面的验证码进行快速验证码,请您务必保护好您的验证码");
theMessage.append("不被别人知晓,这将作为您注册身份的唯一识别码,请妥善处理!
感谢您选择鑫软服务!鑫软工作室将竭诚为您");
theMessage.append("服务!
");
try {
Html_send.sendMessage(smtpHost, from, to, subject, theMessage.toString());
}
catch (MessagingException exc) {
exc.printStackTrace();
}
catch (java.io.UnsupportedEncodingException exc) {
exc.printStackTrace();
}
}
}
(4)进入首页(异步刷新页面实现欢迎语)
window.onload = load();
function load()
{
$.ajax({
type: "POST", //用POST方式传输
url:"/Store/Success", //目标地址 是一个servlet
error: function (XMLHttpRequest, textStatus, errorThrown) { },
success: function (msg){
$('#welcome').html(msg);
$('#register').css("display","none");
$('#hreflogin').attr('href','#');
}
});
}
(5)将指定商品添加至购物车
这一部分实际上只需要使用JS+Java就可以完美呈现
js的核心代码:
var maijia=null;
var img=null;
var name = null;
var price = null;
var chima=null;
var color=null;
$(document).ready(function(){
//根据ul的id来获取下面所有的li元素 并且为每个li配置点击事件
$("#cmlb li").click(function(){
//获取选中的li里面的值
chima=$(this).text();
//把值放在span里面,显示
// $("#tresult").text(v);
// window.alert("chima是:"+chima);
})
})
$(document).ready(function(){
$("#yslb li").click(function(){
color=$(this).text();
// window.alert("color是:"+color);
})
})
$('#sub').on('click', function(){
// window.alert("点击按钮好使");
var spname=document.getElementById('spname');
name=spname.innerText;
var sprice=document.getElementById('price');
price=sprice.innerText;
img=document.getElementById("img").src;
var mj =document.getElementById('maijia');
maijia=mj.innerText;
var num = document.getElementById("num").value;
console.log("数量是:"+num)
$.ajax({
type: "POST", //用POST方式传输
url:"/Store/shopcart", //目标地址 是一个servlet
data:{"chima":chima,"color":color,"number":num,"name":name,"price":price,"img":img,"maijia":maijia},
async:false,
dataType:"json",
error: function (XMLHttpRequest, textStatus, errorThrown) { },
success: function (msg){
if(msg){
// window.location.href = 'cgaddtocart.html';
window.alert("鑫软心选提示您!已成功添加至购物车!");
window.location.href = 'searchList.html';
}
}
});
});
//
//
// var chima = null;
// var color = null;
// var num = null;
// $(document).ready(function(){
// //根据ul的id来获取下面所有的li元素 并且为每个li配置点击事件
// $("#cmlb li").click(function(){
// //获取选中的li里面的值
// chima=$(this).text();
// //把值放在span里面,显示
$("#tresult").text(v);
// })
// $("#yslb li").click(function(){
// color=$(this).text();
// })
//
// })
// $(function pd(){
// num = document.getElementById("num").value;
// window.alert("color是:"+color);
// window.alert("chima是:"+chima);
// window.alert(+"num是:"+num);
// $.ajax({
// type: "POST", //用POST方式传输
// url:"/Store/shopcart", //目标地址 是一个servlet
// data:{"chima":chima,"color":color,"number":num},
// async:false,
// dataType:"json",
// error: function (XMLHttpRequest, textStatus, errorThrown) { }
// });})
java部分后端的核心代码
package com.sinsy.web.Store.cart.list;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.alibaba.fastjson.JSON;
public class list extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user=(String) request.getSession().getAttribute("nickname");
String name =(String) request.getSession().getAttribute("name");
String price = (String) request.getSession().getAttribute("price");
String number = (String) request.getSession().getAttribute("number");
String chima = (String) request.getSession().getAttribute("chima");
String color = (String) request.getSession().getAttribute("color");
String img = (String) request.getSession().getAttribute("img");
String maijia = (String) request.getSession().getAttribute("maijia");
String nickname = (String) request.getSession().getAttribute("nickname");
System.out.println("访问购物车的是"+nickname);
System.out.println(name+"1"+price+"2"+number+"3"+chima+"4"+color+"5"+img+"6"+maijia
+"7"+nickname+"8");
// if(user!=null&&name!=null&&price!=null&&number!=null&&chima!=null
// &&color!=null&&img!=null&&maijia!=null) {
// 给前端返回json对象
String userJson = JSON.toJSONString(UserDAO(name,price,number,chima,color,img,maijia));
response.setContentType("application/json; charset=utf-8");
response.setCharacterEncoding("UTF-8");
OutputStream out = response.getOutputStream();
out.write(userJson.getBytes("UTF-8"));
out.flush();
// }else {
// response.getWriter().write(nickname);
// }
}
public splist UserDAO(String name,String price,String number,String chima,String color,String img,String maijia) {
splist user = new splist();
user.setShangpinname(name);
user.setPrice(price);
user.setNumber(number);
user.setChima(chima);
user.setColor(color);
user.setImagepath(img);
user.setMaijia(maijia);
return user;
}
}
(6)点击付款完成最终交易
这块的话由于只是demo所以我没有做的很突出,需要大家自己去作相应的修改,比如调用银联的支付API或者是支付宝的支付API,下次教程,可能会出一个完整版的前后端带后台管理并且附带支付功能的webDEMO,敬请期待吧!哈哈。