10_MVC

文章目录

  • JSON
    • 常用的JSON解析
    • Jackson的常规使用
      • 指定日期格式
  • MVC设计模式
    • MVC介绍
    • 前后端分离
    • 案例(开发与Json相关接口)
  • 三层架构
    • 三层架构介绍

JSON

  • JSON(JavaScript Object Notation)
    • 是一种轻量级数据交换格式,是存储和交换文本信息的一种语法,它与XML具有相同的特性,是一种数据存储格式,却比 XML 更小、更快、 更易于人编写和阅读、更易于生成和解析。
    • 为了更好的做前端和后端之间的交互

常用的JSON解析

  • fastjson是阿里巴巴的开源JSON解析库
  • Gson是Google提供的JSON解析库
  • Jackson是SpringBoot默认序列化JSON解析库
  • 性能方面,Jackson和FastJson差距很小,Jackson是SpringBoot默认的序列化库,也是最稳定的一个

分别对应的依赖:

<!--Gson-->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.9</version>
</dependency>

<!--fastjson-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.73</version>
</dependency>

<!--jackson-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

Jackson的常规使用

  1. 实例化一个Jackson中用来做序列化的对象ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
  1. 使用ObjectMapper提供的方法完成转换
方法名参数返回值说明
writeValueAsString(Object object):StringObject:被转换的对象String:转换的结果将Object转换为JSONString
readValue(String content,Class<T> valueType):TString content:被转换的字符串;Class<T> valueType:指定接收返回值的类型泛型:在第二个参数被指定的类型将JSONString转换为指定转换类型

eg:

  • bean目录
/**
 *  {
 *      "name":"中国",
 *      "province":[{"name":"黑龙江",”cities”:["哈尔滨","大庆"]},
 *                  {"name":"广东","cities":["广州","深圳","珠海"]},
 *                  {"name":"辽宁","cities":["沈阳", "大连"]},
 *                  {"name":"新疆","cities":["乌鲁木齐"]}
 *                 ]
 *  }
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Country {
    String name;
    List<Province> province;
}

/**
 * {"name":"黑龙江",”cities”:["哈尔滨","大庆"]}
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Province {
    String name;
    String[] cities;
}
  • Execution目录
public class JsonParseExecution {
    @SneakyThrows
    public static void main(String[] args) {
        Country country = new Country();
        country.setName("中国");
        // List<Province> provinces = new ArrayList<>();
        Province province1 = new Province("黑龙江", new String[]{"哈尔滨", "大庆"});
        Province province2 = new Province("广东", new String[]{"深圳", "珠海", "广州"});
        Province province3 = new Province("辽宁", new String[]{"沈阳", "大连"});
        Province province4 = new Province("新疆", new String[]{"乌鲁木齐"});
        List<Province> provinces = Arrays.asList(province1, province2, province3, province4);
        country.setProvince(provinces);

        ObjectMapper objectMapper = new ObjectMapper();
        // 序列化:将country对象转化为字符串
        String jsonStr = objectMapper.writeValueAsString(country);
        System.out.println(jsonStr);
        /**
         * {"name":"中国","province":[{"name":"黑龙江","cities":["哈尔滨","大庆"]},
         * {"name":"广东","cities":["深圳","珠海","广州"]},
         * {"name":"辽宁","cities":["沈阳","大连"]},{"name":"新疆","cities":["乌鲁木齐"]}]}
         */

        // 反序列化:将字符串转换为country对象
        Country jsonCountry = objectMapper.readValue(jsonStr, Country.class);
        System.out.println(jsonStr);
    }
}

指定日期格式

语句:objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));

eg:

  • User中增加一个成员变量Date birthday
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    Integer id;
    String username;
    String password;
    Integer age;
    Date birthday;
    Date createDate;
    String mobile;

    UserDetail userDetail;
}


@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDetail {
    Integer id;
    String email;
    String mobile;
}
  • Execution目录
public class JsonParseExecutionTest {
    @SneakyThrows
    public static void main(String[] args) {
        UserDetail userDetail = new UserDetail(1, "1234@163.com", "12345678909");
        User user = new User(1, "zs", "123456", 22
                , new Date(), new Date(), "12345678900", userDetail);

        ObjectMapper objectMapper = new ObjectMapper();

        // 解决日期格式的语句
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        String userJsonStr = objectMapper.writeValueAsString(user);
        System.out.println(userJsonStr);
        /**
         * {
         *     "id": 1,
         *     "username": "zs",
         *     "password": "123456",
         *     "age": 22,
         *     "birthday": 1711811845446, // 2024-03-30
         *     "createDate": 1711811845446,
         *     "mobile": "12345678900",
         *     "userDetail": {
         *         "id": 1,
         *         "email": "1234@163.com",
         *         "mobile": "12345678909"
         *     }
         * }
         */
    }
}


MVC设计模式

在这里插入图片描述

  1. 这个Servlet可以称之为控制器 → Controller
  2. 查询student信息就是处理数据逻辑 → Model ;另外这部分工作是在Servlet(Controller)中进行的
  3. 将数据和jsp共享 → 在Controller中将Model封装的数据准备就绪
  4. Servlet(Controller)设置转发的jsp(视图View),并且在jsp(视图)中渲染出Model提供的信息

MVC介绍

三个核心部件:

  • 模型(Model)应用程序中用于处理应用程序数据逻辑的部分
    • 获得一些具体的对象,比如说:User的对象、Order的list
  • 视图(View)应用程序中处理数据显示的部分,就是页面的展示,采集用户数据
  • 控制器(Controller)应用程序中处理用户交互的部分。接收用户端的请求,指的是Servlet的功能,根据界面传递过来不同的值进行不同的增删改查操作之后再跳转到不同的界面显示。做一个承上启下的作用。
    • 比如说:requestresponse所处的位置,就是servlet

强制性地使应用程序的输入、处理和输出分开。它们各自处理自己的任务。最典型的MVC就是JSP + Servlet + JavaBean的模式。MVC其实说的就是一个事情:解耦

在这里插入图片描述


前后端分离

通过js向后端发起Ajax异步请求,然后请求到Server服务器,找到对应的控制器,由控制器和Model层和View做交互,最终服务器处理的结果以Json的形式交给JSJS可以直接解析这个Json对象,在前端页面上呈现最终的效果

在这里插入图片描述
也就是我们在Servlet中完成开发之后,响应体中响应的是Json字符串


案例(开发与Json相关接口)

  • 请求相关信息

    • 请求URL:http://localhost:8080/demo3/auth/account/check
    • 请求方法:POST
    • 请求参数:请求参数是JSON字符串
      {"userAccount":"admin123"}
      
  • 提供Postman构造Json数据
    在这里插入图片描述
    在这里插入图片描述

    • 提供filder抓取的请求报文
      在这里插入图片描述

业务:传入的用户名信息,然后完成一些业务,需要在数据库user_t表中根据用户名查询id信息

  • 如果用户名长度小于6响应一段JSON数据

  • {
        "data":null,
        "errmsg":"字符串长度至少6位",
        "errno":400
    }
    
  • 如果用户不存在响应一段JSON数据

  • {
        "data":null,
        "errmsg":"用户不存在",
        "errno":502
    }
    
  • 如果用户存在响应一段JSON数据

  • {
        "data":user的json字符串,
        "errmsg":"用户存在",
        "errno":200
    }
    

eg:

  • bean目录下
@NoArgsConstructor
@Data
public class ResponseVo {
    @JsonProperty("data")
    private Object data;
    @JsonProperty("errmsg")
    private String errmsg;
    @JsonProperty("errno")
    private Integer errno;
    /**
     * {
     *     "data":null,
     *     "errmsg":"字符串长度至少6位",
     *     "errno":400
     * }
     */
}
  • servlet目录下
@WebServlet("/auth/account/*")
public class AuthAccountCheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    @SneakyThrows
    private void process(HttpServletRequest request, HttpServletResponse response) {
        DispatchUtil.dispatch(request, response, this);
    }

    @SneakyThrows
    private void check(HttpServletRequest request, HttpServletResponse response) {
        // JSON字符串:{"userAccount":"admin123"}

        // 首先获得Json字符串并解析它
        String jsonStr = request.getReader().readLine();
        ObjectMapper objectMapper = new ObjectMapper();
        Map map = objectMapper.readValue(jsonStr, Map.class);
        String userAccount = (String) map.get("userAccount");

        String responseStr = null;
        // 判断长度
        if (userAccount == null || userAccount.length() < 3) {
            // 不符合要求
            /**
             * {
             *     "data":null,
             *     "errmsg":"字符串长度至少6位",
             *     "errno":400
             * }
             */
            ResponseVo responseVo = new ResponseVo();
            responseVo.setErrmsg("字符串长度至少6位");
            responseVo.setErrno(400);
            responseStr = objectMapper.writeValueAsString(responseVo);
        }

        UserMapper userMapper = MybatisUtil.getSqlSession().getMapper(UserMapper.class);
        List<User> users = userMapper.selectByUserName(userAccount);
        if (users != null && users.size() > 0) {
            // user存在
            /**
             * {
             *     "data":user的json字符串,
             *     "errmsg":"用户存在",
             *     "errno":200
             * }
             */
            ResponseVo responseVo = new ResponseVo();
            responseVo.setData(users.get(0));
            responseVo.setErrmsg("用户存在");
            responseVo.setErrno(200);
            responseStr = objectMapper.writeValueAsString(responseVo);
        } else {
            // user不存在
            /**
             * {
             *     "data":null,
             *     "errmsg":"用户不存在",
             *     "errno":502
             * }
             */
            ResponseVo responseVo = new ResponseVo();
            responseVo.setErrmsg("用户不存在");
            responseVo.setErrno(502);
            responseStr = objectMapper.writeValueAsString(responseVo);
        }
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println(responseStr);
    }
}

在这里插入图片描述


三层架构

三层架构这里和MVC并不是冲突的概念,而是在MVC的基础上进一步解耦,之前在Controller控制层直接调用了Model,为了后续业务上的解耦,在中间增加增加了一层业务逻辑层,在业务逻辑层中处理大部分业务

在这里插入图片描述

三层架构介绍

  • 三层架构:表示层、业务逻辑层、数据访问层
    • 避免了表示层直接访问数据访问层,表示层只和业务逻辑层有联系,提高了数据安全性
    • 如果切换B/S、C/S架构,直接替换表示层即可,比如替换Servlet
    • 项目结构更清楚,分工明确,增加可维护性

实际在开发过程中的体现,就是控制层(Servlet)中直接调用Service(业务逻辑层),在Service中调用Dao(数据访问层)


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

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

相关文章

【教学类-09-03】20240401细线迷宫图02(A4横版一页-2份竖版)

作品展示&#xff1a; 背景需求&#xff1a; 【教学类-09-02】20240331细线迷宫图01&#xff08;A4横版一页1份横版&#xff09;-CSDN博客文章浏览阅读779次&#xff0c;点赞28次&#xff0c;收藏6次。【教学类-09-02】20240331细线迷宫图01&#xff08;A4横版一页1份横版&…

【2012 统考真题/完整代码】找单词共同后缀的起始位置

题目 假定采用带头结点的单链表保存单词&#xff0c;当两个单词有相同的后缀时&#xff0c;则可共享相同的后缀存储空间&#xff0c;例如&#xff0c;“loading”和“being”的存储映像如下图所示。 设str1和str2分别指向两个单词所在单链表的头结点&#xff0c;链表结点结构为…

PTA L2-043 龙龙送外卖

龙龙是“饱了呀”外卖软件的注册骑手&#xff0c;负责送帕特小区的外卖。帕特小区的构造非常特别&#xff0c;都是双向道路且没有构成环 —— 你可以简单地认为小区的路构成了一棵树&#xff0c;根结点是外卖站&#xff0c;树上的结点就是要送餐的地址。 每到中午 12 点&#…

【Linux】权限理解

权限理解 1. shell命令以及运行原理2. Linux权限的概念3. Linux权限管理3.1 文件访问者的分类&#xff08;人&#xff09;3.2 文件类型和访问权限&#xff08;事物属性&#xff09;3.2.1 文件类型3.2.2 基本权限 3.3 文件权限值的表示方法3.4 文件访问权限的相关设置方法3.4.1 …

Taskflow应用:波前并行(Wavefront Parallelism)

2D的Wavefront如下图所示&#xff1a; #include <taskflow/taskflow.hpp>std::mutex cout_mutex; void format_str(std::string const& str) {std::lock_guard<std::mutex> lock(cout_mutex); std::cout << str << std::endl; }std::string crea…

算法编程:计算斐波那契数列

实现代码&#xff1a;C 实现方法&#xff1a;通过递推法、递归法、矩阵快速幂方法 适用&#xff1a; 范围小且单次查询时&#xff0c;可以不用记忆化处理。 范围大或多次查询时&#xff0c;应使用记忆化处理。 时间复杂度&#xff1a; 递归法&#xff1a;O(n^2)-->递推法(…

三台电机的顺启逆停

1&#xff0c;开启按钮输入信号是 电机一开始启动&#xff0c;5秒回电机2启动 &#xff0c;在5秒电机三启动 关闭按钮输入时电机3关闭 &#xff0c;5秒后电机2关闭 最后电机一关闭 2&#xff0c;思路开启按钮按下接通电机1 并且接通定时器T0 定时器T0 到时候接通电机2 并且开…

YOLOV8逐步分解(3)_trainer训练之模型加载

yolov8逐步分解(1)--默认参数&超参配置文件加载 yolov8逐步分解(2)_DetectionTrainer类初始化过程 接上2篇文章&#xff0c;继续讲解yolov8训练过程中的模型加载过程。 使用默认参数完成训练器trainer的初始化后&#xff0c;执行训练函数train()开始YOLOV8的训练。 1. t…

windows下安装iteliij Idea2023.3

首先从官网下载 双击打开进行安装&#xff1a; 安装完成后&#xff0c;需要对Idea进行稍微处理下。使用我分享给大家的文件&#xff0c;操作以下步骤&#xff1a; 注意&#xff1a;不能打开IDEA软件。 进入到scripts中点击uninstall-all-users.vbs,最后点击确定。 接下来运行in…

如何成功找到理想的工作,java不行了吗?我靠这个方法成功拿到大厂10个offer

第一段&#xff1a;引言 作为一名即将毕业的大学生&#xff0c;步入职场是每个毕业生都要面对的现实挑战。随着社会竞争的日益激烈&#xff0c;如何成功找到一份理想的工作成为许多毕业生所关注的焦点。本文将分享一些关于毕业生求职的经验和建议&#xff0c;希望能够帮助毕业生…

图的遍历试题

一、单项选择题 01.下列关于广度优先算法的说法中&#xff0c;正确的是( ). Ⅰ.当各边的权值相等时&#xff0c;广度优先算法可以解决单源最短路径问题 Ⅱ.当各边的权值不等时&#xff0c;广度优先算法可用来解决单源最短路径问题 Ⅲ.广度优先遍历算法类似于树中的后序遍历算法…

C++中的动态内存管理

1.C中动态内存管理 C语言内存管理方式在C中可以继续使用&#xff0c;但有些地方就无能为力&#xff0c;而且使用起来比较麻烦&#xff0c;因此C又提出了自己的内存管理方式&#xff1a;通过new和delete操作符进行动态内存管理。 1.1 new/delete操作内置类型 c语言和c的动态内存…

Java_22 蓝桥杯真题——拼数

问题描述 给定几 个正整数 a1,a2....,an&#xff0c;你可以将它们任意排序, 现要将这 几 个数字连接成一排&#xff0c;即令相邻数字收尾相接&#xff0c;组成一个数。 问&#xff0c;这个数最大可以是多少。 输入格式 第一行输入个正整数 n(l < n< 20)。 第二行输入几 个…

Linux USB驱动(二)

1. Linux USB驱动软件框架 应用程序有两种访问硬件的途径&#xff1a;通过设备驱动程序来访问和跳过设备驱动程序&#xff08;直接使用host驱动程序&#xff09;来访问。 当直接使用Host驱动程序时&#xff0c;可以调用libusb库中已经封装好的函数接口。 2. USB电气信号 一个…

特征融合篇 | 利用RT-DETR的AIFI去替换YOLOv8中的SPPF(附2种改进方法)

前言:Hello大家好,我是小哥谈。RT-DETR模型是一种用于目标检测的深度学习模型,它基于transformer架构,特别适用于实时处理序列数据。在RT-DETR模型中,AIFI(基于注意力的内部尺度特征交互)模块是一个关键组件,它通过引入注意力机制来增强模型对局部和全局信息的处理能力…

2024全开源小狐狸ai付费创作系统V2.8.0

源码介绍 小狐狸GPT付费体验系统的开发基于国外很火的ChatGPT&#xff0c;这是一种基于人工智能技术的问答系统&#xff0c;可以实现智能回答用户提出的问题。相比传统的问答系统&#xff0c;ChatGPT可以更加准确地理解用户的意图&#xff0c;提供更加精准的答案。同时&#x…

从0开始搭建基于VUE的前端项目(三) Vuex的使用与配置

准备与版本 vuex 3.6.2(https://v3.vuex.vuejs.org/zh/)概念 vuex是什么? 是用作 【状态管理】的 流程图如下 state 数据状态,成员是个对象 mapState 组件使用this.$store.state.xxx获取state里面的数据 getters 成员是个函数,方便获取state里面的数据,也可以加工数据 ma…

HarmonyOS 应用开发之组件启动规则(Stage模型)

启动组件是指一切启动或连接应用组件的行为&#xff1a; 启动UIAbility、ServiceExtensionAbility、DataShareExtensionAbility&#xff0c;如使用startAbility()、startServiceExtensionAbility()、startAbilityByCall()等相关接口。 连接ServiceExtensionAbility、DataShare…

[BT]BUUCTF刷题第12天(3.31)

第12天 Basic BUU BURP COURSE 1 经过尝试&#xff0c;在这里X-Forwarded-For不管用&#xff0c;要用X-Real-IP BP抓包添加X-Real-IP:127.0.0.1&#xff08;注意这一行前面不要有空行&#xff09; 发送后返回提示了用户名和密码&#xff0c;这里直接给了&#xff0c;登录即可…

unity学习(78)--unity调试--长痛不如短痛

1.在vs2022中&#xff0c;工具--获取工具与功能。 2. 安装图中工具&#xff0c;原来我早就安装了。 3 f9下断 同时点击图中按钮 vs此时变为如下状态 unity中出现如下提示&#xff1a; 4 在unity中运行游戏&#xff0c;vs这边确实成功断住了&#xff01;