基于Springboot的web后端开发三层架构上手实操

引言

我们拿到了xml文件

我们要将将xml文件中的数据加载并解析

完成数据的处理

并且返回给前端页面(result格式)

1.将xml文件放在resources目录下

xml是我们需要解析的文件

 查看xml文件

2.在springboot中引入dom4j依赖

解析xml需要在springboot中引入dom4j依赖

这边我们在springboot工程中已经引入依赖并重新构建了maven

3.引入工具类XmlParserUtils

工具类放入java文件夹下的总包(公司域名反写)的util工具包下

这里引入的是一个解析xml文件的工具类XmlParserUtils

参数是xml文件路径和实例化的类的类型

返回值是list集合

package com.bigdate.threetier_architecture.util;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.lang.reflect.Constructor;
import java.util.*;
import java.io.File;
import java.util.ArrayList;

public class XmlParserUtils{
    public static <T> List<T> parse(String file,Class<T> targetClass){
        ArrayList<T> list=new ArrayList<T>();
        try {
            //获取一个解析器对象
            SAXReader saxReader=new SAXReader();
            //利用解析器把xml文件加载到内存中 并且返回一个文档对象
            Document document=saxReader.read(new File(file));
            //获取到根标签
            Element rootElement =document.getRootElement();
            //通过根标签来获取user标签
            List <Element> elements=rootElement.elements("emp");

            //遍历集合,得到每一个user标签
            for(Element element:elements){
                //获得name属性
                String name=element.element("name").getText();
                //获得age属性
                String age=element.element("age").getText();
                //获得gender属性
                String gender=element.element("gender").getText();
                //获得job属性
                String job=element.element("job").getText();

                //组装数据
                Constructor<T>constructor=targetClass.getDeclaredConstructor(String.class,Integer.class,String.class,String.class);
                constructor.setAccessible(true);
                T object=constructor.newInstance(name,Integer.parseInt(age),gender,job);

                //把数据添加到集合里面去
                list.add(object);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return  list;
    }
}

4.编写实体类emp和统一响应结果类Result

不管是实体类还是统一响应结果类

我们都将其放在pojo包下

且都是用javabean封装的

实体类emp 标准的javabean 这样就能通过创建对象的方式封装emp的各属性

注意数据类型都是包装类

package com.bigdate.threetier_architecture.pojo;

public class Emp {
    private  String name;
    private  Integer age;
    private String gender;
    private String job;

    public Emp() {
    }

    public Emp(String name, Integer age, String gender, String job) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.job = job;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * 获取
     * @return gender
     */
    public String getGender() {
        return gender;
    }

    /**
     * 设置
     * @param gender
     */
    public void setGender(String gender) {
        this.gender = gender;
    }

    /**
     * 获取
     * @return job
     */
    public String getJob() {
        return job;
    }

    /**
     * 设置
     * @param job
     */
    public void setJob(String job) {
        this.job = job;
    }

    public String toString() {
        return "Emp{name = " + name + ", age = " + age + ", gender = " + gender + ", job = " + job + "}";
    }
}

统一响应结果result类

这个类主要是给前端页面一个统一响应的响应结果

统一后端返回对象

result类包含三个成员属性和三个静态方法

package com.bigdate.threetier_architecture.pojo;

public class Result {

    private Integer code;
    //响应的状态码
    private String msg;
    //响应的信息 如success
    private Object data;
    //响应回的数据 数据类型为Object

    public Result() {
    }

    public Result(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

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

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

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

    public String toString() {
        return "Result{code = " + code + ", msg = " + msg + ", data = " + data + "}";
    }

    //定义静态方法 帮助我们快速构建result对象

    //有数据时响应成功返回 会自动补齐其他参数
    public static Result success(Object data){
        return new Result(1,"success",data);
    }
    
    //没有任何数据返回 即使成功返回成员属性data也是null 
    public static Result success(){
        return new Result(1,"success",null);
    }

    //响应的信息多种多样 仅仅返回响应信息 应该直接放到成员属性的位置
    public static Result success(String msg){
        return new Result(1,msg,null);
    }
}

 架构展示

5.数据 -- dao层

我们采用的面向接口的编程方式

先写规则接口 然后用实现类去填充

接口

package com.bigdata.dao;

import com.bigdata.pojo.Emp;

import java.util.List;

/*
* 面向接口编程
* 接口的实现类必须重写接口里的所有方法
* 如应对以后我们从不同地方拿到数据 如xml 本地文件 数据库 服务器
* 所以我们先写接口 定义统一的规则 就是从哪里拿取数据
* 之后通过创建接口实现类的方式从指定地方拿取数据
* */

public interface EmpDao {
    //获取员工列表数据
    public List<Emp> listEmp();
}

实现类实现了接口并重写了方法

加载了xml文件 调用工具类XmlParserUtils来解析

package com.bigdata.dao.impl;

import com.bigdata.dao.EmpDao;
import com.bigdata.pojo.Emp;
import com.bigdata.util.XmlParserUtils;

import java.util.List;

//接口的实现类A
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1.加载并解析xml文件
        String file=this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList=XmlParserUtils.parse(file, Emp.class);
        return empList;
    }

}

6.核心逻辑 -- service层

最主要的一层

接口 与刚刚一样 接口中只有一个属性 集合

说明我们在service层中的实现类中依然是要对 存储在list内的数据进行处理

package com.bigdata.service;

import com.bigdata.pojo.Emp;

import java.util.List;

public interface EmpService {
    //获取员工列表数据
    public List<Emp>listEmp();
}

接口的实现类 处理代码的核心逻辑

其中我们的list集合从dao层获取

我们要获取的集合就是那个从service层接口的实现类已经处理好的集合

package com.bigdata.service.impl;

import com.bigdata.dao.EmpDao;
import com.bigdata.dao.impl.EmpDaoA;
import com.bigdata.pojo.Emp;
import com.bigdata.service.EmpService;

import java.util.List;

public class EmpServiceA implements EmpService {
    //service层拿取集合要从dao层获取 调用dao获取数据
    private EmpDao empDao=new EmpDaoA();
    @Override
    public List<Emp> listEmp() {
        //拿到dao对象
        List<Emp> empList=empDao.listEmp();
        //2.对数据进行转换处理
        empList.stream().forEach(emp ->{

            //处理gender
            String gender=emp.getGender();
            if(gender.equals("1")){
                emp.setGender("男");
            }else emp.setGender("女");

            //处理job
            String job=emp.getJob();
            if(job.equals("1")){
                emp.setJob("学生");
            }else emp.setJob("老师");

        });
        return empList;
    }
}

7.控制器 -- controller层

不需要书写接口

我们将前dao层和service处理的数据已经放到集合里面去

我们要将集合返回 而这个集合去service层中去拿

service层的集合又是从dao层获取的并经过逻辑处理的

package com.bigdata.controller;

import com.bigdata.pojo.Emp;
import com.bigdata.pojo.Result;
import com.bigdata.service.EmpService;
import com.bigdata.service.impl.EmpServiceA;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class Controller {

    private EmpService empService=new EmpServiceA();

    @RequestMapping("/listEmp")
    public Result list(){

        //调用service响应数据 再响应数据
        List<Emp> empList=empService.listEmp();

        //3.响应数据
        return Result.success(empList);
        
    }

}

8.前端页面展示

启动spingboot

 访问本地网址 进行展示

总结

定义的每一个对外暴露的方法我们都称为功能接口

引号内的是功能接口的访问路径

如果用户从前端页面获取数据

先是给controller层发起响应

controller层向service层发起请求 

servece层向dao层拿取数据

dao层再去翻数据源

那我们的代码应该从这时候开始写

所以我们会选择先书写dao层的代码 

然后回调给service层 service再传递给controller层 

想了一晚上 所以我认为我们在实际后端开发中就是书写数据回调的代码

我们在书写三层架构的代码时是

先写接口 再写实现类

即面向接口编程 

接口的事项类必须重写接口中的所有方法

如我们以后从不同地方拿到数据 如数据库 云数据库 本地文件 服务器

所以我们先写接口定义统一的规则的 就是从哪里拿取数据 之后用实现类重写方法

三层架构分工明确利于书写

前一层的数据都是后一层获取的 而排在最最后的的是数据源 最前面的是前端页面

吐槽

草你爸 没有xml文件和工具类本多直接动手搓别让我再见类引入三字 累死了!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker——部署LNMP架构

目录 一、LNMP架构概述 1.项目环境 2.服务器环境 3.需求 二、搭建Linux系统基础镜像 三、部署Nginx 1.建立工作目录 2.编写Dockerfile脚本 3.准备Nginx.conf配置文件 4.生成镜像 5.创建自定义网络 6.启动镜像容器 7.验证Nginx 三、部署Mysql 1.建立工作目录 2.编…

【STM32+HAL】读取电池电量

一、准备工作 有关CUBEMX的初始化配置&#xff0c;参见我的另一篇blog&#xff1a;【STM32HAL】CUBEMX初始化配置 有关定时器触发ADC模式配置&#xff0c;详见【STM32HAL】ADC采集波形实现 有关软件触发ADC模式配置&#xff0c;详见【STM32HAL】三轴按键PS2摇杆 二、所用工具…

Python赋值运算符

目录 赋值运算符 将值赋给变量&#xff1a; 做加法运算之后完成赋值&#xff1a; 做减法运算之后完成赋值&#xff1a;- 做乘法运算之后完成赋值&#xff1a;* 做除法运算之后完成赋值&#xff1a;/ 做整除运算之后完成赋值&#xff1a;// 做幂次运算之后完成赋值&#xff1a;*…

自动驾驶框架 UniAD环境部署

感谢大佬们的开源工作 UniAD-github地址-YYDS更多bev算法部署参考如果您觉得本帖对您有帮助&#xff0c;感谢您一键三连支持一波^_^ 统一自动驾驶框架 (UniAD) &#xff0c;第一个将全栈驾驶任务整合到一个深度神经网络中的框架&#xff0c;并可以发挥每个子任务以及各个模块的…

【MySQL 数据宝典】【索引原理】- 004 优化示例-join in exist

一、join 优化原理 1.1 基本连接方式介绍 JOIN 是 MySQL 用来进行联表操作的&#xff0c;用来匹配两个表的数据&#xff0c;筛选并合并出符合我们要求的结果集。 1.2 驱动表的定义 1.2.1 什么是驱动表 多表关联查询时,第一个被处理的表就是驱动表,使用驱动表去关联其他表.驱…

基于springboot的考勤管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Zynq 7000 系列中成功执行BootROM的条件

Zynq 7000设备的启动需要正确的电压序列和I/O引脚控制。BootROM的流程由复位类型、启动模式引脚设置以及启动映像来控制。BootROM对所选启动设备的引脚连接有特定的要求。 Zynq 7000 SoC设备具有电源、时钟和复位要求&#xff0c;这些要求必须得到满足&#xff0c;才能成功执行…

java:SpringBootWeb请求响应

Servlet 用java编写的服务器端程序 客户端发送请求至服务器 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器 服务器将响应返回给客户端 javaweb的工作原理 在SpringBoot进行web程序开发时,内置了一个核心的Servlet程序DispatcherServlet,称之…

RocketMQ快速入门:namesrv、broker、dashboard的作用及消息发送、消费流程(三)

0. 引言 接触rocketmq之后&#xff0c;大家首当其冲的就会发现需要安装3个组件&#xff1a;namesrv, broker, dashboard&#xff0c;其中dashboard也叫console&#xff0c;为选装。而这几个组件之前的关系是什么呢&#xff0c;消息发送和接收的过程是如何传递的呢&#xff0c;…

应用实战 | 别踩白块小游戏,邀请大家来PK挑战~

“踩白块会输”是一个简单的微信小程序游戏&#xff0c;灵感来自当年火热的别踩白块游戏&#xff0c;程序内分成三个模块&#xff1a;手残模式、经典模式和极速模式&#xff0c;分别对应由易到难的三种玩法&#xff0c;可以查看游戏排名。动画效果采用JS实现&#xff0c;小程序…

Spark-机器学习(6)分类学习之支持向量机

在之前的文章中&#xff0c;我们学习了分类学习之朴素贝叶斯算法&#xff0c;并带来简单案例&#xff0c;学习用法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢…

基于YOLOV8+Pyqt5无人机航拍太阳能电池板检测系统

1.YOLOv8的基本原理 YOLOv8是一种前沿的目标检测技术&#xff0c;它基于先前YOLO版本在目标检测任务上的成功&#xff0c;进一步提升了性能和灵活性&#xff0c;在精度和速度方面都具有尖端性能。在之前YOLO 版本的基础上&#xff0c;YOLOv8 引入了新的功能和优化&#xff0c;…

SpringBoot 常用注解总结超详细(面试)

目录 一、组件相关&#x1f381; Controller Service Repository Component 二、依赖注入相关&#x1f349; Autowired Resource 根据类型注入&#xff08;By Type&#xff09; 根据名称注入&#xff08;By Name&#xff09; 区别 Qualifier Resource 和 Qualifie…

C语言浮点型数据在内存中的存储及取出等的介绍

文章目录 前言一、浮点型在内存中的存储二、浮点数存储规则三、浮点数在内存中的存储&#xff08;32位&#xff09;float类型四、浮点数在内存中的存储&#xff08;64位&#xff09;double类型五、指数E从内存中取出分成三种情况1. E不全为0或不全为12. E全为03. E全为1 六、有…

设计模式之工厂模式FactoryPattern(二)

一、简单工厂 package com.xu.demo.factoryPattern;/*** 简单工厂模式类*/ public class SimpleFactoryPattern {public static Phone create(String name) {//根据输入对象名称判断返回相匹配的对象if("IPhone".equals(name)) {//返回对象return new IPhone();}else…

Java算法--队列

队列 队列介绍 队列是一个有序列表&#xff0c;可以用数组或是链表来实现。遵循先入先出的原则。即&#xff1a;先存入队列的数据&#xff0c;要先取出。后存入的要后取出 数组模拟队列思路 队列本身是有序列表&#xff0c;若使用数组的结构来存储队列的数据&#xff0c;则…

自动驾驶新书“五一”节马上上市了

我和杨子江教授合写的《自动驾驶系统开发》终于在清华大学出版社三校稿之后即将在五一节后出版。 清华大学汽车学院的李克强教授和工程院院士撰写了序言。 该书得到了唯一华人图灵奖获得者姚期智院士、西安交大管晓宏教授和科学院院士以及杨强教授和院士等的推荐&#xff0c;…

git变更远端仓库名之后如何修改本地仓库配置的另一种方法?(删remote指针、添加、绑定master)

背景 如果某个远端的仓库地址变化后&#xff0c;本地仓库可以修改对应的remote。 之前谈过几种方法&#xff0c;比如重新设置一个新的remote的指针&#xff0c;绑定到新地址。然后删除origin&#xff0c;然后把新指针mv到origin。比如直接seturl修改&#xff08;git remote se…

基于HTML+CSS+JavaScript的表白网页

基于HTMLCSSJavaScript的表白网页 前言效果截图&#xff08;为GIF格式&#xff09;部分代码领取源码下期更新预报 前言 大部分人都有喜欢的人&#xff0c;学会这个表白代码&#xff0c;下次表白你肯定会成功。 效果截图&#xff08;为GIF格式&#xff09; 部分代码 index.htm…

使用 Python 和 DirectShow 从相机捕获图像

在 Python 中使用 OpenCV 是视觉应用程序原型的一个非常好的解决方案,它允许您快速起草和测试算法。处理从文件中读取的图像非常容易,如果要处理从相机捕获的图像,则不那么容易。OpenCV 提供了一些基本方法来访问链接到 PC 的相机(通过对象),但大多数时候,即使对于简单的…
最新文章