03 - Servlet (二) 🛬
Servlet 综合案例(用户登录,注册)
前台页面代码 菜单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>菜单</title>
<link rel="stylesheet" href="static/layui/css/layui.css" />
</head>
<body>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">layui 后台布局</div>
<!-- 头部区域(可配合layui已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<li class="layui-nav-item"><a href="">控制台</a></li>
<li class="layui-nav-item"><a href="">商品管理</a></li>
<li class="layui-nav-item"><a href="">用户</a></li>
<li class="layui-nav-item">
<a href="javascript:;">其它系统</a>
<dl class="layui-nav-child">
<dd><a href="">邮件管理</a></dd>
<dd><a href="">消息管理</a></dd>
<dd><a href="">授权管理</a></dd>
</dl>
</li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<img src="http://t.cn/RCzsdCq" class="layui-nav-img" />
贤心
</a>
<dl class="layui-nav-child">
<dd><a href="">基本资料</a></dd>
<dd><a href="">安全设置</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="">退了</a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">所有商品</a>
<dl class="layui-nav-child">
<dd><a href="item.html">商品管理</a></dd>
<dd><a href="javascript:;">列表二</a></dd>
<dd><a href="javascript:;">列表三</a></dd>
<dd><a href="">超链接</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">解决方案</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">列表一</a></dd>
<dd><a href="javascript:;">列表二</a></dd>
<dd><a href="">超链接</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="">云市场</a></li>
<li class="layui-nav-item"><a href="">发布商品</a></li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<iframe src="" frameborder="0" id="menu" style="width: 100%; height: 1080px;"></iframe>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
© layui.com - 底部固定区域
</div>
</div>
<script src="static/layui/layui.js"></script>
<script>
//JavaScript代码区域
layui.use(['element', 'jquery'], function () {
var element = layui.element
var $ = layui.jquery
/**
* 页面加载时,运行
*/
$(function () {
//获取所有的a标签
$('dd a').click(function (e) {
e.preventDefault() //取消所有a标签的默认行为
//获取iframe对象,给它的src赋值 ,赋值内容是点击的每一个a标签的href属性
$('#menu').attr('src', $(this).attr('href'))
})
})
})
</script>
</body>
</html>
数据表格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<link rel="stylesheet" href="static/layui/css/layui.css" />
</head>
<body>
<!--搜索开始-->
<!--搜索功能可以自己私下做一下-->
<!--搜索结束-->
<!--表格开始-->
<table class="layui-hide" id="test" lay-filter="test"></table>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="add">添加</button>
</div>
</script>
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
<!--表格结束-->
<!--弹出层开始-->
<div id="saveOrUpdate" style="display: none">
<form class="layui-form" lay-filter="dataForm" id="dataForm">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">商品id</label>
<div class="layui-input-inline">
<input type="tel" name="id" lay-verify="required" autocomplete="off" class="layui-input" />
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">商品名称</label>
<div class="layui-input-inline">
<input type="text" name="name" lay-verify="required" autocomplete="off" class="layui-input" />
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">商品单价</label>
<div class="layui-input-inline">
<input type="tel" name="price" lay-verify="required" autocomplete="off" class="layui-input" />
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">商品库存</label>
<div class="layui-input-inline">
<input type="text" name="count" lay-verify="required" autocomplete="off" class="layui-input" />
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">商品状态</label>
<div class="layui-input-inline">
<input type="tel" name="status" lay-verify="required" autocomplete="off" class="layui-input" />
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-inline">
<input type="text" name="type" lay-verify="required" autocomplete="off" class="layui-input" />
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">上架时间</label>
<div class="layui-input-inline">
<input type="tel" name="date" lay-verify="required" autocomplete="off" class="layui-input" />
</div>
</div>
</div>
<div class="layui-form-item" style="text-align: center">
<div class="layui-input-block">
<button type="button" class="layui-btn layui-btn-normal" lay-submit="" lay-filter="dataForm">立即提交</button>
<button type="reset" class="layui-btn layui-btn-warm">重置</button>
</div>
</div>
</form>
</div>
<!--弹出层结束-->
<script src="static/layui/layui.js"></script>
<script>
layui.use(['jquery', 'table', 'layer', 'form'], function () {
var table = layui.table
var $ = layui.jquery
var layer = layui.layer
var form = layui.form
//温馨提示:默认由前端自动合计当前行数据。从 layui 2.5.6 开始: 若接口直接返回了合计行数据,则优先读取接口合计行数据。
//详见:https://www.layui.com/doc/modules/table.html#totalRow
var myTable = table.render({
elem: '#test',
//请求的地址
url: 'itemServlet?method=queryList',
toolbar: '#toolbarDemo',
title: '商品数据表',
cols: [
[
{ type: 'checkbox', fixed: 'left' },
{ field: 'id', title: '商品ID', fixed: 'left', unresize: true, sort: true, totalRowText: '合计' },
{ field: 'name', title: '商品名称', edit: 'text' },
{ field: 'price', title: '商品价格', edit: 'text' },
{ field: 'count', title: '商品库存', sort: true, totalRow: true },
{ field: 'type', title: '商品分类', edit: 'text', sort: true },
{
field: 'status',
title: '商品状态',
sort: true,
totalRow: true,
templet: function (res) {
return res.status == 1 ? '上架' : '已下架'
}
},
{ field: 'date', title: '上架时间', sort: true, totalRow: true },
{ fixed: 'right', title: '操作', toolbar: '#barDemo' }
]
],
page: true
})
//工具栏事件
table.on('toolbar(test)', function (obj) {
var checkStatus = table.checkStatus(obj.config.id)
switch (obj.event) {
case 'add':
openAddItem()
break
}
})
var url
//定义个返回值代表弹出层
var indexForm
//添加商品
function openAddItem() {
indexForm = layer.open({
type: 1,
title: '添加商品',
content: $('#saveOrUpdate'),
area: ['800px'],
//打开弹出层成功时的回调函数
success: function (index) {
//清空表格
$('#dataForm')[0].reset()
url = 'itemServlet?method=insert'
}
})
}
//修改商品
function openUpdateItem(data) {
indexForm = layer.open({
type: 1,
title: '修改商品',
content: $('#saveOrUpdate'),
area: ['800px'],
//打开弹出层成功时的回调函数
success: function (index) {
//回显数据
form.val('dataForm', data)
url = 'itemServlet?method=modify'
}
})
}
//表单提交
form.on('submit(dataForm)', function () {
//序列化表单
var params = $('#dataForm').serialize()
//发送ajax请求
$.get(
url,
params,
function (data) {
//给出提示信息
if (data.code == 1) {
layer.msg(data.msg)
} else {
layer.msg(data.msg)
}
//关闭弹出层
layer.close(indexForm)
//刷新表格
myTable.reload()
},
'json'
)
})
//监听行工具事件
table.on('tool(test)', function (obj) {
var data = obj.data //date就是每一行的数据
console.log(data)
if (obj.event === 'del') {
layer.confirm('真的删除行么', function (index) {
$.get('itemServlet?method=delete&id=' + data.id, function (data) {})
obj.del() //这就是删除具体的一行 表面删除
layer.close(index)
})
} else if (obj.event === 'edit') {
openUpdateItem(data)
}
})
})
</script>
</body>
</html>
模型代码 也就是返回给页面的数据格式
package com.softeem.dto;
public class Model {
private int code;
private String msg;
private int count;
private Object data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
dao 实现类
package com.softeem.dao.impl;
import com.softeem.dao.ItemDao;
import com.softeem.entity.Item;
import com.softeem.utils.DBUtils3;
import java.util.List;
public class ItemDaoImpl implements ItemDao {
@Override
public List<Item> selectList() {
String sql = "select * from item";
return DBUtils3.queryList(Item.class,sql);
}
@Override
public boolean insert(Item item) {
String sql = "insert into item values(?,?,?,?,?,?,?)";
return DBUtils3.exeUPdate(sql,item.getId(),item.getName(),item.getPrice(),
item.getCount(),item.getStatus(),item.getType(),item.getDate());
}
}
dao 接口
package com.softeem.dao;
import com.softeem.entity.Item;
import java.util.List;
public interface ItemDao {
List<Item> selectList();
boolean insert(Item item);
}
servlet 类
import com.alibaba.fastjson.JSON;
import com.softeem.dao.ItemDao;
import com.softeem.dao.impl.ItemDaoImpl;
import com.softeem.dto.Model;
import com.softeem.entity.Item;
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 java.io.IOException;
import java.util.List;
@WebServlet("/itemServlet")
public class ItemServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//第一步 处理请求的乱码
req.setCharacterEncoding("utf-8");
//第二步 处理响应的乱码
resp.setContentType("text/html;charset=utf-8");
//第三步 接受要处理的请求
String method = req.getParameter("method");
//第四步 通过method的值来决定执行哪个方法
switch (method){
case "queryList":
queryList(req,resp);
break;
case "insert":
insert(req,resp);
break;
case "modify":
modify(req,resp);
break;
case "delete":
delete(req,resp);
break;
}
}
/**
* 添加商品
* @param req
* @param resp
*/
private void insert(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//告诉页面,数据以json数据形式返回
resp.setContentType("application/json;charset=utf-8");
//接受所有的数据
String id = req.getParameter("id");
String name = req.getParameter("name");
String price = req.getParameter("price");
String type = req.getParameter("type");
String count = req.getParameter("count");
String date = req.getParameter("date");
String status = req.getParameter("status");
//创建一个商品的对象 把数据封装成一个对象
Item item = new Item(Integer.parseInt(id),name,Double.parseDouble(price),Integer.parseInt(count),
Integer.parseInt(status),type,date);
System.out.println(item);
//创建dao层对象
ItemDao itemDao = new ItemDaoImpl();
//调用dao层查询所有商品列表
boolean result = itemDao.insert(item);
//创建一个model对象
Model model = new Model();
if(result){
model.setCode(1);
model.setMsg("添加成功");
}else{
model.setCode(0);
model.setMsg("添加失败");
}
//把model转化为json数据
String json = JSON.toJSONString(model);
System.out.println(json);
resp.getWriter().write(json);
}
/**
* 修改商品
* @param req
* @param resp
*/
private void modify(HttpServletRequest req, HttpServletResponse resp) {
}
/**
* 删除商品
* @param req
* @param resp
*/
private void delete(HttpServletRequest req, HttpServletResponse resp) {
}
/**
* 查询所有商品列表
* @param req
* @param resp
*/
private void queryList(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//创建dao层对象
ItemDao itemDao = new ItemDaoImpl();
//调用dao层查询所有商品列表
List<Item> list = itemDao.selectList();
//创建一个model对象
Model model = new Model();
model.setCode(0);
model.setMsg("");
model.setCount(20);
model.setData(list);
//把model转化为json数据
String json = JSON.toJSONString(model);
System.out.println(json);
resp.getWriter().write(json);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
数据响应之 JSON 插件使用
在 Servlet 中可以使用 response 获取输出流(PrintWriter),然后通过输出流对象将数据响应到客户端(web 前端),由于前端的语言种类很多,因此不同的语言之间传递的对象语法格式差异较大,因此,无法直接将 java 对象传递前端(不认识);所以多数时候后端只能发送字符串数据到前端,但是如需要发送复杂的数据,则需要 JSON 字符串(主流)支持;
在 java 中存在非常多的开源的 JSON 插件:
- fastJSON 阿里巴巴提供的
- Gson 谷歌提供的
- Jackson
- Json-lib
- ....
fastJSON 用法
public static void main(String[] args) {
Tbuser u = new Tbuser();
u.setId(5);
u.setUsername("ZyKun");
u.setPassword("123456");
u.setCellphone("18632186327");
u.setEmail("7e25@40koxoo.xyz");
Model model = new Model(1, "登录成功", u);
//将Java对象转换为JSON字符串
//fastJson
String json = JSON.toJSONString(model);
System.out.println("json字符串" + json);
//解析json字符串为目前项目中存在java类型对象
Model m = JSON.parseObject(json, Model.class);
System.out.println("Java对象" + m);
//解析json字符串为JSONObject(没有预定的java类型时使用)
String myjson = "{\"id\":1001,\"stuName\":\"狗蛋\",\"age\":18}";
JSONObject jsonObject = JSON.parseObject(myjson);
System.out.println(jsonObject.getIntValue("id"));
System.out.println(jsonObject.getString("stuName"));
System.out.println(jsonObject.getIntValue("age"));
List<Tbuser> users = new ArrayList<>();
users.add(new Tbuser(1, "softeem", "123", "110", "110@163.com"));
users.add(new Tbuser(2, "jack", "123", "120", "120@163.com"));
users.add(new Tbuser(3, "tomcat", "123", "130", "130@163.com"));
users.add(new Tbuser(4, "spring", "123", "140", "140@163.com"));
users.add(new Tbuser(5, "mybatis", "123", "150", "150@163.com"));
users.add(new Tbuser(6, "spring cloud", "163", "160", "160@163.com"));
//将Java集合转换为JSON字符串
String listJson = JSON.toJSONString(users);
System.out.println(listJson);
//将json字符串解析为java集合对象
List<Tbuser> tbusers = JSON.parseArray(listJson, Tbuser.class);
tbusers.forEach(i -> System.out.println(i));
}
请求转发与重定向
url-pattern 详解与请求路径问题
Servlet 处理多个请求
以往在客户端发送请求到服务端时,每一个 Servlet 只做一件事情(即一个功能点),一旦对于功能需求比较多系统来说,就会需要大量的 Servlet 来处理请求,不利于统一管理,因此,可以将对于某一个模块(用户模块,订单模块,商品模块,购物车模块)的操作单独用一个 Servlet 类解决该模块的所有操作(增删改查:CRUD)
作业
基于 Layui+Servlet+JSON 实现一个单表的 CRUD 操作,例如一个商品内容管理系统中的商品管理模块:
(商品 id,名称,单价,库存,分类,上架时间,状态:是否上架)