目录
1、 创建BaseServlet继承HttpServlet重写service方法
2、创建不同对象的Servlet将不同的Servlet封装成方法

参照 Web案例
在pom.xml中再导入fastjson坐标
- <dependency>
- <groupId>com.alibabagroupId>
- <artifactId>fastjsonartifactId>
- <version>1.2.62version>
- dependency>
通过Element官网的代码编写基于Vue的前端页面

注意在Vue中使前后端信息交互使用axios异步请求实现
在Vue的data数据中创建数据模型,使后端的数据传递到前端模型中
- data() {
- return {
- //当前页码
- currentPage: 1,
- //对话框默认为false隐藏
- dialogVisible: false,
-
- //品牌模型数据
- brand: {
- status: '',
- brandName: '',
- companyName:'',
- id:'',
- ordered:'',
- description:''
- },
- //表格数据模型
- tableData: [{
- brandName: '三只松鼠',
- companyName: '三只松鼠',
- description: 'dsds',
- ordered: '10',
- status: '1',
- }],
- /*复选框选中的数据集合*/
- multipleSelection: []
- }
- }
再通过遍历将数据库中的结果展示
- <el-table
- :data="tableData"
- style="width: 100%"
- @Selection-change="handleSelectionChange"
- :row-class-name="tableRowClassName">
- <el-table-column
- type="selection"
- width="55">
- el-table-column>
- <el-table-column
- type="index"
- width="50">
- el-table-column>
- <el-table-column
- //对应模型中的名称
- prop="brandName"
- label="品牌名称"
- align="center">
- el-table-column>
- <el-table-column
- prop="companyName"
- label="企业名称"
- align="center">
- el-table-column>
- <el-table-column
- prop="description"
- label="企业描述"
- align="center">
- el-table-column>
- <el-table-column
- prop="ordered"
- align="center"
- label="排序">
- el-table-column>
- <el-table-column
- prop="status"
- align="center"
- label="当前状态">
- el-table-column>
- <el-table-column
- align="center"
- label="操作">
-
- <el-row>
- <el-button type="primary">修改el-button>
-
- <el-button type="danger">删除el-button>
- el-row>
- el-table-column>
- el-table>
前端页面向后端发送axios异步请求,使用Vue的生命周期mounted 使在页面加载完成后发送异步请求获取数据,将查询所有封装成方法,内部使用axios异步请求
- mounted(){
- //页面加载完成后发送异步请求获取数据
- this.selectAll();
- },
-
- methods: {
- //查询所有数据
- selectAll(){
- var _this=this
- //页面加载完成后发送异步请求获取数据
- axios({
- method:"get",
- url:"http://localhost:8080/webcore_case_war/brand/selectAll"
- }).then(function (resp){
- //将后端数据传递给前端模型
- _this.tableData = resp.data;
- })
- },
这里需要注意:在axios中的this为undefined,他不能代表Vue中的数据,而Vue中的this始终指向Vue,所以要使用this做回调函数,需要在axios外部对this进行处理。
后端Servlet的逻辑
- //通过service方法返回sql结果
- List
brandList = brandService.selectAll(); -
- //将返回的结果响应到页面
- //将List集合转换为JSON
- String brands = JSON.toJSONString(brandList);
-
- //将结果相应到页面
- resp.setContentType("text/json;charset=utf-8");
- PrintWriter writer = resp.getWriter();
- writer.write(brands);

后端需要注意的是:在service层中要使用接口规范Brand对象的方法,然后再service下创建包impl存放实现类。
前端代码
前端创建表单通过axios异步请求携带表单数据提交到后端进行处理
-
- <el-dialog
- title="添加品牌"
- :visible.sync="dialogVisible"
- width="30%"
- :before-close="handleClose">
-
- <el-form ref="form" :model="brand" label-width="80px">
- <el-form-item label="品牌名称">
- <el-input v-model="brand.brandName">el-input>
- el-form-item>
- <el-form-item label="企业名称">
- <el-input v-model="brand.companyName">el-input>
- el-form-item>
- <el-form-item label="排序">
- <el-input v-model="brand.ordered">el-input>
- el-form-item>
- <el-form-item label="企业描述">
- <el-input type="textarea" v-model="brand.description">el-input>
- el-form-item>
- <el-form-item label="状态">
- <el-switch v-model="brand.status"
- //按钮的switch逻辑,开启按钮表示status为1
- active-value="1"
- inactive-value="0">
- el-switch>
- el-form-item>
- <el-form-item>
- <el-button type="primary" @click="addBrand">立即创建el-button>
- <el-button @click="dialogVisible = false">取消el-button>
- el-form-item>
- el-form>
-
- span>
- el-dialog>
使用addBrand方法通过axios携带表单数据提交到后台数据库,再调用查询所有的方法
- //提交新增数据
- addBrand() {
- var _this = this;
- //发送异步请求,携带表单数据
- axios({
- method:"post",
- url:"http://localhost:8080/webcore_case_war/brand/addBrand",
- //携带表单数据
- data:_this.brand
- }).then(function (resp){
- //判断后端返回的是否是success字符串
- if (resp.data == "success"){
- //添加成功关闭窗口
- _this.dialogVisible = false;
-
- //再次查询数据
- _this.selectAll();
-
- //添加成功弹出消息
- _this.$message({
- message: '恭喜你,添加成功',
- type: 'success'
- })
- }
- })
- },
后端逻辑
前端的JSON数据要使用流读取
- //获取前端数据,前端数据是以JSON格式提交的,使用流读取
- BufferedReader reader = req.getReader();
- String s = reader.readLine(); //对应的JSON字符串
- //将对应的JSON字符串转为java对象
- Brand brand = JSON.parseObject(s, Brand.class);
-
- //将获取的数据封装到数据库
- brandService.addBrand(brand);
-
- //响应成功的标识
- resp.getWriter().write("success");
由于每实现一个功能就要创建一个Servlet,会使得Servlet的文件越来越多,因此对后端Servlet进行代码优化
可以发现所有的Servlet都使用了doGet和doPost方法实现数据转发,而doGet、doPost是Servlet内部写好的方法,所以我们可以重写HttpServlet中的方法分发的方法,来实现一个对象对应一个Servlet的操作代码,将所有的Servlet代码都写在一个Servlet中,通过其他的Servlet封装成方法进行调用即可。

- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.lang.reflect.Method;
-
- public class BaseServlet extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //1、获取请求路径
- String uri = req.getRequestURI(); // webcore_case_war/brand/selectAll
-
- //2、获取最后一段路径--方法名
- int index = uri.lastIndexOf('/');
- //获取方法名
- //直接使用index会包含/
- String methodName = uri.substring(index + 1);
-
- //3、执行方法
- //3.1、获取方法的class类文件
- //哪个方法调用这个service,这个this就代表哪个方法的对象
- //例如BrandServlet和UserServlet,两个Servlet对象,这两个Servlet继承BaseServlet,都会调用这个service方法
- //如果是BrandServlet中的selectAll方法调用service方法,那么这个this就代表BrandServlet对象
- Class extends BaseServlet> cls = this.getClass();
-
- try {
- //3.2、通过class文件反射,获取方法
- //(方法名称,方法携带的参数)方法携带的参数HttpServletRequest、HttpServletResponse也要加进去
- //每个方法都会携带参数HttpServletRequest、HttpServletResponse
- Method method = cls.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
-
- //3.3、获取方法后执行方法
- //方法反射告诉对象调用这个方法 方法名.invoke(对象名,携带的参数)
- method.invoke(this,req,resp);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
- }
通过/brand/* *号通配符,需要访问那个功能就将方法名替换*号
- import com.alibaba.fastjson.JSON;
- import com.itheima.pojo.Brand;
- import com.itheima.service.impl.BrandServiceImpl;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.List;
-
- @WebServlet("/brand/*")
- public class BrandServlet extends BaseServlet{
-
- //实现类要创建对象才能调用
- private BrandServiceImpl brandService = new BrandServiceImpl();
-
- public void selectAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
- //通过service方法返回sql结果
- List
brandList = brandService.selectAll(); -
- //将返回的结果响应到页面
- //将List集合转换为JSON
- String brands = JSON.toJSONString(brandList);
-
- //将结果相应到页面
- resp.setContentType("text/json;charset=utf-8");
- PrintWriter writer = resp.getWriter();
- writer.write(brands);
- }
-
- public void addBrand(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
- //获取前端数据,前端数据是以JSON格式提交的,使用流读取
- BufferedReader reader = req.getReader();
- String s = reader.readLine(); //对应的JSON字符串
- //将对应的JSON字符串转为java对象
- Brand brand = JSON.parseObject(s, Brand.class);
-
- //将获取的数据封装到数据库
- brandService.addBrand(brand);
-
- //响应成功的标识
- resp.getWriter().write("success");
- }
- }

前端逻辑
- //删除按钮
- handleDelete(row) {
- this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
- cancelButtonText: '取消',
- confirmButtonText: '确定',
- type: 'warning'
- }).then(() => {
- //异步请求后端删除数据
- var _this = this;
- axios({
- method:"post",
- url:"http://localhost:8080/webEndingCase_war/brand/deleteBrandById",
- //将一行数据的数据携带传给后端
- //在html中声明了携带的是id值
- data:row
- }).then(function (resp) {
- //删除逻辑
- if (resp.data == "success") {
- //删除成功,自动关闭窗口
- //刷新数据,重新查询
- _this.selectAll();
- }
- }),
- this.$message({
- type: 'success',
- message: '删除成功!'
- });
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- },
后端逻辑
- public void selectBrandById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
-
- //获取前端数据,前端数据是以JSON格式提交的,使用流读取
- BufferedReader reader = req.getReader();
- String id = reader.readLine(); //对应的JSON字符串
-
- //调用service方法
- Brand brand = brandService.selectBrandById(Integer.parseInt(id));
-
- //将brand对象转成JSON字符串
- String s = JSON.toJSONString(brand);
-
- //将JSON字符串发送给前端
- //相应给前端的字符串也要设置编码否则会乱码
- resp.setContentType("text/json;charset=utf-8");
- resp.getWriter().write(s);
- }
技术难点:
- <el-table-column
- prop="id"
- align="center"
- label="操作">
-
- <template slot-scope="scope">
-
- <el-button type="primary" @click="handleSelect(scope.row.id),updatedialogVisible = true">修改el-button>
- <el-button type="danger" @click="handleDelete(scope.row.id)">删除el-button>
- template>
- el-table-column>
在当前的操作栏隐藏对应的id值
再在对应单元格标签中添加属性 slot-scope="scope",在按钮的点击方法中声明参数scope.row.id,就可以获取该行数据的id值,也可以获取其他值。
![]()
在vue框架中
点击修改后进行数据回显,通过id获取数据响应给前端,修改数据后再点击提交修改,后端实现修改逻辑

前端逻辑
- //提交修改逻辑
- handleUpdate(){
- var _this = this;
- //发送异步请求,携带表单数据
- axios({
- method: "post",
- url: "http://localhost:8080/webEndingCase_war/brand/updateBrand",
- //携带表单数据
- data:_this.updatebrand
- }).then(function (resp) {
- //判断后端返回的是否是success字符串
- if (resp.data == "success") {
- //添加成功关闭窗口
- _this.updatedialogVisible = false;
-
- //再次查询数据
- _this.selectAll();
-
- //添加成功弹出消息
- _this.$message({
- message: '恭喜你,修改成功',
- type: 'success'
- })
- }
- })
- },
-
- //点击修改后数据回调给页面
- handleSelect(row){
- var _this = this
- //提交异步请求
- //将一行数据的id值传递给后端
- axios({
- method:"post",
- url:"http://localhost:8080/webEndingCase_war/brand/selectBrandById",
- data:row
- }).then(function (resp) {
- //将回调的数据传给updateBrand模型
- _this.updatebrand = resp.data;
- })
- },
后端逻辑
- public void selectBrandById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
-
- //获取前端数据,前端数据是以JSON格式提交的,使用流读取
- BufferedReader reader = req.getReader();
- String id = reader.readLine(); //对应的JSON字符串
-
- //调用service方法
- Brand brand = brandService.selectBrandById(Integer.parseInt(id));
-
- //将brand对象转成JSON字符串
- String s = JSON.toJSONString(brand);
-
- //将JSON字符串发送给前端
- //相应给前端的字符串也要设置编码否则会乱码
- resp.setContentType("text/json;charset=utf-8");
- resp.getWriter().write(s);
- }
-
- public void updateBrand(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
- //解决前端发送数据乱码问题
- req.setCharacterEncoding("UTF-8");
- //获取前端数据,前端数据是以JSON格式提交的,使用流读取
- BufferedReader reader = req.getReader();
- String s = reader.readLine(); //对应的JSON字符串
- System.out.println(s);
- //将对应的JSON字符串转为java对象
- Brand brand = JSON.parseObject(s, Brand.class);
- System.out.println(brand);
- //调用service
- brandService.updateBrand(brand);
-
- //修改成功向前端响应标识
- resp.getWriter().write("success");
- }
技术难点:


遇到的难题:

对前端返回的字符串进行输出发现中文格式乱码
解决方法:
在servlet中添加如下代码解决中文乱码问题
req.setCharacterEncoding("UTF-8");



前端逻辑
- //删除逻辑
- for (let i = 0; i < this.multipleSelection.length; i++) {
- let selectionbrand = this.multipleSelection[i];
- //将选中的id传入deleteIds模型中
- this.deleteIds[i] = selectionbrand.id;
- }
- var _this = this;
- //发送异步请求,携带表单数据
- axios({
- method: "post",
- url: "http://localhost:8080/webEndingCase_war/brand/deleteBrandByIds",
- //携带表单数据
- data: _this.deleteIds
- }).then(function (resp) {
- //判断后端返回的是否是success字符串
- if (resp.data == "success") {
-
- //再次查询数据
- _this.selectAll();
- }
- })
后端逻辑
- public void deleteBrandByIds(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
- //接收前端数据 id数组[1,2,8]
- BufferedReader reader = req.getReader();
- String params = reader.readLine();
-
- //将得到的JSON格式的id数组转为int型数组
- int[] ids = JSON.parseObject(params, int[].class);
-
- //调用service方法
- brandService.deleteBrandByIds(ids);
-
- //响应给前端结果
-
- resp.getWriter().write("success");
-
- }
技术难点:




前端逻辑
- //查询分页数据
- selectByPage() {
- var _this = this;
- axios({
- method:"get",
- url:"http://localhost:8080/webEndingCase_war/brand/selectByPage?currentPage="+_this.currentPage+"&pageSize="+_this.pageSize
- }).then(function (resp) {
- //_this.tableData = resp.data; 当前后端传递的数据是{"pageData":[{"brandName":"联想","companyName":"联想有限公司"}
- //JSON字符串格式,不能直接放入表格
- //通过resp.data. 来获取不同的数据
- _this.tableData = resp.data.pageData;
- _this.totalCount = resp.data.totalCount;
- })
- },
-
- handleCurrentChange(val) {
- console.log(`当前页: ${val}`);
- //点击切换当前页,赋值给当前页模型
- this.currentPage = val;
- this.selectByPage();
- },
- //分页方法
- handleSizeChange(val) {
- console.log(`每页 ${val} 条`);
- this.pageSize = val;
- this.selectByPage();
- },
后端逻辑
- public void selectByPage(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
- //前端通过get请求 使用url将当前页码和当前页数据传到后端 url?currentPage=1&pageSize=10
- String currentPage = req.getParameter("currentPage");
- String pageSize = req.getParameter("pageSize");
-
- //调用service方法
- PageBean
pageBean = brandService.selectByPage(Integer.parseInt(currentPage), Integer.parseInt(pageSize)); -
- //将java对象转成JSON格式
- String jsonString = JSON.toJSONString(pageBean);
-
- //将JSON数据发送给前端
- resp.setContentType("text/json;charset=utf-8");
- resp.getWriter().write(jsonString);
- }
技术难点:
需要将当前分页页面数据和总数据条数封装成对象一起传递到前端


将查询全部、分页查询和多条件查询进行整合,使他们都使用同一个方法

前端逻辑
修改selectAll方法的查询逻辑,在url后面拼字符串,并且以post请求方式将多条件查询的参数传给后端,参数封装成了selectBrand模型,将来一访问页面就会进行默认的分页查询
- //查询分页数据
- selectByPage() {
- axios({
- //在then的外面可以直接使用this
- method:"post",
- url:"http://localhost:8080/webEndingCase_war/brand/selectByPageAndCondition?currentPage="+this.currentPage+"&pageSize="+this.pageSize,
- data:this.selectBrand
- }).then(resp => {
- //_this.tableData = resp.data; 当前后端传递的数据是{"pageData":[{"brandName":"联想","companyName":"联想有限公司"}
- //JSON字符串格式,不能直接放入表格
- //通过resp.data. 来获取不同的数据
- this.tableData = resp.data.pageData;
- this.totalCount = resp.data.totalCount;
- })
- },
后端逻辑
- public void selectByPageAndCondition(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
-
- req.setCharacterEncoding("UTF-8");
-
- //前端通过get请求 使用url将当前页码和当前页数据传到后端 url?currentPage=1&pageSize=10
- String currentPage = req.getParameter("currentPage");
- String pageSize = req.getParameter("pageSize");
-
- System.out.println(currentPage);
- //获取前端对应的查询条件对象
- //接收前端数据
- BufferedReader reader = req.getReader();
- String params = reader.readLine();
- System.out.println(params);
- //将得到的JSON格式转为brand对象
- Brand brand = JSON.parseObject(params,Brand.class);
- System.out.println(brand);
-
- //调用service方法
- PageBean
pageBean = brandService.selectByPageAndCondition(Integer.parseInt(currentPage), Integer.parseInt(pageSize),brand); - System.out.println(pageBean);
-
- //将java对象转成JSON格式
- String jsonString = JSON.toJSONString(pageBean);
-
- //将JSON数据发送给前端
- resp.setContentType("text/json;charset=utf-8");
- resp.getWriter().write(jsonString);
- }
技术难点:

