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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 基于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文件和工具类本多直接动手搓别让我再见类引入三字 累死了!

目录
相关文章
|
3天前
|
设计模式 算法 搜索推荐
后端开发中的设计模式应用
在软件开发的浩瀚海洋中,设计模式犹如一座座灯塔,为后端开发者指引方向。本文将深入探讨后端开发中常见的设计模式,并通过实例展示如何在实际项目中巧妙应用这些模式,以提升代码的可维护性、扩展性和复用性。通过阅读本文,您将能够更加自信地应对复杂后端系统的设计与实现挑战。
21 3
|
4天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的医院门诊预约挂号系统
基于Java+Springboot+Vue开发的医院门诊预约挂号系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的门诊预约挂号管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
27 2
基于Java+Springboot+Vue开发的医院门诊预约挂号系统
|
4天前
|
JavaScript 前端开发 API
深入浅出Node.js后端开发
【9月更文挑战第23天】在这篇文章中,我们将探索Node.js的世界,了解它如何改变后端开发的面貌。通过实际案例和代码示例,我们不仅学习Node.js的核心概念,还会深入探讨它的高级特性,如异步编程、事件驱动模型以及微服务架构的应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和实用技能,帮助你构建更高效、可扩展的后端系统。
35 19
|
11天前
|
设计模式 架构师 Java
Java开发工程师转架构师需要学习什么
Java开发工程师转型为架构师需掌握多项技能:精通Java及框架、数据库与分布式系统;熟悉设计模式与架构模式;积累项目经验;提升沟通与领导力;持续学习新技术;培养系统设计与抽象能力;了解中间件及开发工具;并注重个人特质与职业发展。具体路径应结合个人目标与实际情况制定。
39 18
|
1天前
|
JavaScript 开发者
深入理解Node.js事件循环及其在后端开发中的应用
【8月更文挑战第57天】本文将带你走进Node.js的事件循环机制,通过浅显易懂的语言和实例代码,揭示其背后的工作原理。我们将一起探索如何高效利用事件循环进行异步编程,提升后端应用的性能和响应速度。无论你是Node.js新手还是有一定经验的开发者,这篇文章都能给你带来新的启发和思考。
|
2天前
|
存储 运维 负载均衡
后端开发中的微服务架构实践与思考
本文旨在探讨后端开发中微服务架构的应用及其带来的优势与挑战。通过分析实际案例,揭示如何有效地实施微服务架构以提高系统的可维护性和扩展性。同时,文章也讨论了在采用微服务过程中需要注意的问题和解决方案。
|
1天前
|
Web App开发 缓存 JavaScript
深入浅出Node.js后端开发
【9月更文挑战第26天】本文将引导你了解Node.js的基本原理,并通过实际案例展示如何在后端开发中应用它。我们将从Node.js的核心概念讲起,逐步深入到构建一个完整的后端服务,最后探讨如何优化你的Node.js应用。准备好让你的开发技能更上一层楼了吗?让我们一起潜入Node.js的世界!
|
7天前
|
设计模式 算法 搜索推荐
后端开发中的设计模式应用
在软件开发的浩瀚海洋中,设计模式犹如灯塔一般指引着方向。它们不是一成不变的规则,而是前人智慧的结晶。本文将深入探讨几种在后端开发中常用的设计模式,如单例、工厂、观察者和策略模式,并阐述如何在实际项目中灵活运用这些模式来提升代码质量、可维护性和扩展性。通过对比传统开发方式与应用设计模式后的差异,我们将揭示设计模式在解决复杂问题和优化系统架构中的独特价值。
|
2天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【9月更文挑战第25天】本文将带你了解Node.js的基本概念和核心优势,同时提供一些实际的代码示例来加深理解。无论你是初学者还是有一定经验的开发者,都能通过本文获得有价值的信息和技巧。让我们一起探索Node.js的世界吧!
|
3天前
|
机器学习/深度学习 缓存 NoSQL
深度学习在图像识别中的应用与挑战后端开发中的数据缓存策略
本文深入探讨了深度学习技术在图像识别领域的应用,包括卷积神经网络(CNN)的原理、常见模型如ResNet和VGG的介绍,以及这些模型在实际应用中的表现。同时,文章也讨论了数据增强、模型集成等改进性能的方法,并指出了当前面临的计算资源需求高、数据隐私等挑战。通过综合分析,本文旨在为深度学习在图像识别中的进一步研究和应用提供参考。 本文探讨了后端开发中数据缓存的重要性和实现方法,通过具体案例解析Redis在实际应用中的使用。首先介绍了缓存的基本概念及其在后端系统性能优化中的作用;接着详细讲解了Redis的常见数据类型和应用场景;最后通过一个实际项目展示了如何在Django框架中集成Redis,