文章目录
- 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的常规使用
- 实例化一个Jackson中用来做序列化的对象
ObjectMapper 
ObjectMapper objectMapper = new ObjectMapper();
 
- 使用
ObjectMapper提供的方法完成转换 
| 方法名 | 参数 | 返回值 | 说明 | 
|---|---|---|---|
writeValueAsString(Object object):String | Object:被转换的对象 | String:转换的结果 | 将Object转换为JSONString | 
readValue(String content,Class<T> valueType):T | String 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设计模式

- 这个Servlet可以称之为控制器 → Controller
 - 查询student信息就是处理数据逻辑 → Model ;另外这部分工作是在Servlet(Controller)中进行的
 - 将数据和jsp共享 → 在Controller中将Model封装的数据准备就绪
 - Servlet(Controller)设置转发的jsp(视图View),并且在jsp(视图)中渲染出Model提供的信息
 
MVC介绍
三个核心部件:
- 模型(Model)应用程序中用于处理应用程序数据逻辑的部分 
  
- 获得一些具体的对象,比如说:
User的对象、Order的list 
 - 获得一些具体的对象,比如说:
 - 视图(View)应用程序中处理数据显示的部分,就是页面的展示,采集用户数据
 - 控制器(Controller)应用程序中处理用户交互的部分。接收用户端的请求,指的是Servlet的功能,根据界面传递过来不同的值进行不同的增删改查操作之后再跳转到不同的界面显示。做一个承上启下的作用。 
  
- 比如说:
request和response所处的位置,就是servlet 
 - 比如说:
 
强制性地使应用程序的输入、处理和输出分开。它们各自处理自己的任务。最典型的MVC就是JSP + Servlet + JavaBean的模式。MVC其实说的就是一个事情:解耦。

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

 也就是我们在Servlet中完成开发之后,响应体中响应的是Json字符串
案例(开发与Json相关接口)
-  
请求相关信息
- 请求URL:
http://localhost:8080/demo3/auth/account/check - 请求方法:
POST - 请求参数:请求参数是
JSON字符串{"userAccount":"admin123"} 
 - 请求URL:
 -  
提供Postman构造Json数据


- 提供filder抓取的请求报文

 
 - 提供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(数据访问层)
![[中级]软考_软件设计_计算机组成与体系结构_06_ 流水线技术](https://img-blog.csdnimg.cn/direct/d38be02d7a6b4c6083e376a985d6f6fc.png)


















