Java Web —— 第五天(请求响应2)

news2024/11/27 22:31:24

响应数据

@ResponseBody

类型:方法注解、类注解

位置: Controller方法上/类上

作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合,将会转换为JSON格式响应

说明: @RestController = @Controller + @ResponseBody ;

package com.example.springboot01.controller;

import com.example.springboot01.pojo.Address;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @author hyk~
 */

@RestController
public class ResponseController {
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("Hello");
        return "hello";
    }

    @RequestMapping("/getAddr")
    public Address getAddr(){
        Address addr = new Address();
        addr.setCity("长沙");
        addr.setProvince("湖南");
        return addr;
    }

    @RequestMapping("/listAddr")
    public List<Address> listAddr(){
        List<Address> list = new ArrayList<>();

        Address addr1 = new Address();
        addr1.setProvince("湖北");
        addr1.setCity("武汉");

        Address addr2 = new Address();
        addr2.setCity("南京");
        addr2.setProvince("江苏");

        list.add(addr1);
        list.add(addr2);

        return list;

    }
}

 不易管理 难以维护

修改代码

编写 Result

Result 类是一个响应结果的封装类,用于统一封装接口的返回结果。它有以下几个属性:

  • code: 用于表示操作的结果,1表示成功,0表示失败。
  • msg: 提示信息,如操作成功或失败的原因。
  • data: 实际返回的数据,可以是任何类型的对象(Object)。

此外,Result 类提供了多个构造方法、getter和setter方法,以及一些静态方法,用于快速生成Result对象:

  • Result.success(Object data): 返回成功的Result对象,并携带数据。
  • Result.success(): 返回成功的Result对象,但不携带数据。
  • Result.error(String msg): 返回失败的Result对象,并携带失败信息。
package com.example.springboot01.pojo;

/**
 * 统一响应结果封装类
 */
public class Result {
    private Integer code;//1 成功 , 0 失败
    private String msg; //提示信息
    private Object data; //数据 data

    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 static Result success(Object data) {
        return new Result(1, "success", data);
    }

    public static Result success() {
        return new Result(1, "success", null);
    }

    public static Result error(String msg) {
        return new Result(0, msg, null);
    }

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

ResponseController

package com.example.springboot01.controller;

import com.example.springboot01.pojo.Address;
import com.example.springboot01.pojo.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @author hyk~
 */

@RestController
public class ResponseController {

    @RequestMapping("/hello")
    public Result hello(){
        System.out.println("Hello");
        //return new Result(1,"success","Hello");
        return Result.success("Hello");
    }

    @RequestMapping("/getAddr")
    public Result getAddr(){
        Address addr = new Address();
        addr.setCity("长沙");
        addr.setProvince("湖南");
        return Result.success(addr);
    }

    @RequestMapping("/listAddr")
    public Result listAddr(){
        List<Address> list = new ArrayList<>();

        Address addr1 = new Address();
        addr1.setProvince("湖北");
        addr1.setCity("武汉");

        Address addr2 = new Address();
        addr2.setCity("南京");
        addr2.setProvince("江苏");

        list.add(addr1);
        list.add(addr2);

        return Result.success(list);

    }
}

类之间的关联

  • 使用关系:
    • ResponseController 中的方法通过调用 Result.success() 静态方法,生成 Result 对象。这些 Result 对象封装了控制器的返回结果,统一了接口的响应格式。

作用总结

  • Result 类的作用:

    • 提供了一个统一的响应格式,使得所有接口的返回值结构一致,便于前端解析和处理。
    • 可以通过 code 来判断操作是否成功,通过 msg 提示信息,通过 data 传递实际的数据。
  • ResponseController 类的作用:

    • 处理HTTP请求,生成相应的数据或信息,并通过 Result 类封装成统一格式的响应返回给客户端。

1. @ResponseBody

位置: Controller类上/方法上

作用: 将方法返回值直接响应,若返回值类型是 实体对象/集合 ,转SON格式响应

2.统一响应结果

Result (code、msg、data )

案例

获取员工数据,返回统一响应结果,在页面渲染展示

加载并解析emp.xml文件中的数据,完成数据处理,并在页面展示。

在pom.xml文件中引入dom4j的依赖,用于解析XML文件

引入资料中提供的解析XML的工具类XMLParserUtils、对应的实体类Emp,XML文件emp.xml

引入资料中提供的静态页面文件,放在resources下的static目录下

编写Controller程序,处理请求,响应数据

package com.example.springboot01.controller;

import com.example.springboot01.pojo.Emp;
import com.example.springboot01.pojo.Result;
import com.example.springboot01.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author hyk~
 */

@RestController
public class EmpController {

    @RequestMapping("/listEmp")
    public Result list(){
        //1.加载并解析emp.xml文件
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        
        //2.对数据进行转换处理 -gender job
        empList.stream().forEach(emp -> {
            //处理gender
            String gender = emp.getGender();
            if ("1".equals(gender)){
                emp.setGender("男");
            }else if ("2".equals(gender)){
                emp.setGender("女");
            }

            //处理job     1: 讲师, 2: 班主任 , 3: 就业指导
            String job = emp.getJob();
            if ("1".equals(job)){
                emp.setJob("讲师");
            } else if ("2".equals(job)) {
                emp.setJob("班主任");
            }else if ("3".equals(job)) {
                emp.setJob("就业指导");
            }
        });

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

}

复用性差 难以维护

三层架构

controller: 控制层,接收前端发送的请求,对请求进行处理,并响应数据

service: 业务逻辑层,处理具体的业务逻辑。

dao: 数据访问层(Data Access bject)(持久层),负责数据访问操作,包括数据的增、删、改、查

1.创建对应的包

 

2.编写dao数据访问层代码 数据访问操作

Empdao接口

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

实现类

public class EmpDaoA  implements EmpDao {

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

 2.service业务逻辑层 业务逻辑处理

public interface EmpService {
//    获取员工列表
    public List<Emp> listEmp();
}
public class EmpServiceA implements EmpService {
    private  EmpDao empDao = new EmpDaoA();
    @Override
    public List<Emp> listEmp() {
        //1.调用dao 获取数据
        List<Emp> empList = empDao.listEmp();
        //2.对数据进行转换处理 -gender job
        empList.stream().forEach(emp -> {
            //处理gender
            String gender = emp.getGender();
            if ("1".equals(gender)){
                emp.setGender("男");
            }else if ("2".equals(gender)){
                emp.setGender("女");
            }

            //处理job     1: 讲师, 2: 班主任 , 3: 就业指导
            String job = emp.getJob();
            if ("1".equals(job)){
                emp.setJob("讲师");
            } else if ("2".equals(job)) {
                emp.setJob("班主任");
            }else if ("3".equals(job)) {
                emp.setJob("就业指导");
            }
        });
        return empList;
    }
}

3.controller控制层  接收请求 响应数据

@RestController
public class EmpController {
    private EmpService empService = new EmpServiceA();
    @RequestMapping("/listEmp")
    public Result list(){
        //调用Service,获取数据
        List<Emp> empList = empService.listEmp();
        //响应数据
        return Result.success(empList);
    }
}

易于管理,维护 复用性强

分层解耦

内聚:软件中各个功能模块内部的功能联系

耦合:衡量软件中各个层/模块之间的依赖、关联的程度

软件设计原则:高内聚低耦合。

控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转

依赖注入:Dependency lnjection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。

Bean对象:IOC容器中创建、管理的对象,称之为bean

IOC& DI入门

1.Service层及 Dao层的实现类,交给IOC容器管理

2.为Controller及Service注入运行时,依赖的对象

3.运行测试

示例代码

EmpServiceA类
package com.example.springboot01.service.impl;

import com.example.springboot01.dao.EmpDao;
import com.example.springboot01.dao.impl.EmpDaoA;
import com.example.springboot01.pojo.Emp;
import com.example.springboot01.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author hyk~
 */
@Component //将当前类交给IOC容器管理 成为IOC容器中的bean
public class EmpServiceA implements EmpService {
//    private  EmpDao empDao = new EmpDaoA();
    @Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 —— 依赖注入
    private  EmpDao empDao;

    @Override
    public List<Emp> listEmp() {
        //1.调用dao 获取数据
        List<Emp> empList = empDao.listEmp();
        //2.对数据进行转换处理 -gender job
        empList.stream().forEach(emp -> {
            //处理gender
            String gender = emp.getGender();
            if ("1".equals(gender)){
                emp.setGender("男");
            }else if ("2".equals(gender)){
                emp.setGender("女");
            }

            //处理job     1: 讲师, 2: 班主任 , 3: 就业指导
            String job = emp.getJob();
            if ("1".equals(job)){
                emp.setJob("讲师");
            } else if ("2".equals(job)) {
                emp.setJob("班主任");
            }else if ("3".equals(job)) {
                emp.setJob("就业指导");
            }
        });
        return empList;
    }
}
EmpDaoA类
package com.example.springboot01.dao.impl;

import com.example.springboot01.dao.EmpDao;
import com.example.springboot01.pojo.Emp;
import com.example.springboot01.utils.XmlParserUtils;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author hyk~
 */
@Component //将当前类交给IOC容器管理 成为IOC容器中的bean
public class EmpDaoA  implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1.加载并解析emp.xml文件
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

EmpController类
package com.example.springboot01.controller;

import com.example.springboot01.pojo.Emp;
import com.example.springboot01.pojo.Result;
import com.example.springboot01.service.EmpService;
import com.example.springboot01.service.impl.EmpServiceA;
import com.example.springboot01.utils.XmlParserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author hyk~
 */

@RestController
public class EmpController {

    @Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 —— 依赖注入
    private EmpService empService;
//    private EmpService empService = new EmpServiceA();

    @RequestMapping("/listEmp")
    public Result list(){
        //调用Service,获取数据
        List<Emp> empList = empService.listEmp();
        //响应数据
        return Result.success(empList);
    }
}

IOC容器详解

Bean的声明

要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一

bean的名字默认为类名的首字母小写 

可以通过 value 修改

注意事项

声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写

使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能

用@Controller

Bean组件扫描

1.前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描

2.@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解

@SpringBootApplicatiol中,默认扫描的范围是启动类所在包及其子包。

声明bean的注解

@Component,@Controller, @Service,@Repository

@SpringBootApplication具有包扫描作用,默认扫描当前包及其子包

DI详解

Bean注入

@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出如下错误

通过以下几种方案来解决:

@Primary

通过@Primary设置EmpServiceB类为优先类

@Qualifier

 在@Autowired上通过@Qualifier来指定bean

@Resource 

    @Resource(name = "empServiceB")
     private EmpService empService;

依赖注入的注解

默认按照类型自动装配,@Autowired

如果同类型的bean存在多个

@Primary

@Autowired +@Qualifier("bean的名称”)

@Resource(name="bean的名称”)

@Resource 与 @Autowired区别

@Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

@Autowired 默认是按照类型注入,而@Resource默认是按照名称注入

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嘉实基金“青黄不接”:董事长赵学军被调查,明星经理基金绿油油

尚未实现“打造中国版的贝莱德”之梦&#xff0c;手握万亿资产管理规模的嘉实基金便“出事”了。 近日&#xff0c;嘉实基金在官网披露了一则临时公告&#xff0c;称其于2024年8月9日从相关方面获悉&#xff0c;该公司董事长赵学军因个人问题正配合有关部门调查。目前&#xf…

录音怎么转换成mp3格式?6款免费音频转换mp3的软件大公开!(赶紧收藏)

录音怎么转换成mp3格式&#xff1f;录音是我们日常记录生活和工作的常见方式之一。然而&#xff0c;不同的音频格式往往会带来兼容性和播放上的困难。如果您曾因为无法播放某个录音而烦恼&#xff0c;或者希望能够方便地将录音转换成mp3格式&#xff0c;那么本文就能告诉您答案…

那些年我们一起遇到过的奇技淫巧

EVAL长度限制突破技巧 PHP Eval函数参数限制在16个字符的情况下 &#xff0c;如何拿到Webshell&#xff1f; 写一段限制长度在小于17位的字符&#xff0c;拿下webshell <?php highlight_file(__FILE__); $param $_REQUEST[param]; if (strlen($param) < 17 &&am…

【安卓】播放多媒体文件

文章目录 播放音频播放视频 播放音频 在Android中播放音频文件一般是使用MediaPlayer类实现的&#xff0c;它对多种格式的音频文件提供了非常全面的控制方法&#xff0c;从而使播放音乐的工作变得十分简单。 MediaPlayer类中常用的控制方法。 常用方法名描述setDataSource()设…

合作文章(IF=14.3)|RNA-Seq和ChIP-Seq助力SOX12调节肝癌细胞的机制研究以及肝癌联合治疗的免疫策略的发现

肝细胞癌(HCC)是全球严重的健康负担。长期以来&#xff0c;HCC的治疗选择很少&#xff0c;但免疫检查点阻断(ICB)近年来取得了重大突破。在肿瘤免疫微环境(TIME)中&#xff0c;免疫细胞通过配对的免疫检查点或其他信号与肿瘤细胞相互作用&#xff0c;形成异质的免疫抑制生态系统…

AI高级肖像动画神器LivePortrait

文章目录 前言一、安装1.1 源码安装1.2 windows一键启动包 二、人像生成2.1 浏览器2.2 输入图像2.3 选择驱动视频2.4 生成2.5 结果 三、动物生成3.1 浏览器3.2 输入图片3.3 选择视频3.4 生成3.5 最终结果 四、软件获取 前言 最近&#xff0c;快手可灵大模型团队、中国科学技术…

go 事件机制(观察者设计模式)

背景&#xff1a; 公司目前有个业务&#xff0c;收到数据后&#xff0c;要分发给所有的客户端或者是业务模块&#xff0c;类似消息通知这样的需求&#xff0c;自然而然就想到了事件&#xff0c;观察者比较简单就自己实现以下&#xff0c;确保最小功能使用支持即可&#xff0c;其…

LeetCode旋转图像

题目描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3]…

100 Exercises To Learn Rust 挑战!构文・整数・变量

前一篇文章 【0】准备 【1】构文・整数・变量 ← 本次全部文章列表 《100 Exercise To Learn Rust》第2回&#xff0c;也就是实际演习的第1回&#xff01;从这次开始&#xff0c;我们会适度减少前置说明&#xff0c;直接进入问题的解决&#xff01; 本次的相关页面 1.1. Syn…

VUE3请求意外报跨越错误或者500错误问题

1.有可能是请求传参和传参类型写错了 首先要确保该请求接口是支持跨域的&#xff08;不支持叫后端改&#xff09; access-control-allow-headers:Content-Type, Accept, Access-Control-Allow-Origin, api_key, Authorization access-control-allow-methods:GET, POST, OPTIO…

【docker】dockerfile部署lnmp、docker compose初步

1、dockerfile部署lnmp mkdir /opt/lnmp cd /opt/lnmp mkdir nginx mysql php docker network create --subnet20.0.0.0/24 lnmp-net将wordpress文件夹拷贝到nginx、php文件夹 /opt/nginx/Dockerfile: # 使用官方的nginx镜像作为基础镜像 FROM nginx:latest# 复制默认配置文件…

【QGroundControl二次开发】十. QT添加GStreamer视频播放同时保存

上一章介绍使用QT播放GStreamer视频流 【QGroundControl二次开发】八. QT实现播放gstreamer视频。 这章介绍如何在原有基础上保存为视频&#xff0c;同时保存为一个个规定大小的小视频。 一. 思想 之前的文章展示了如何在QT中播放GST视频流&#xff0c;这章在原有的基础上增加…

vue-cli(二)

箭头函数 一般的函数&#xff1a; 这里window是用来调用函数的 function fun(){console.log(this) } window.fun(); 箭头函数&#xff1a; 1、如果只有一个参数&#xff0c;形参的小括号可以省略 2、如果只有一条语句&#xff0c;{}可以省略 完整的写法 let fun2 a>…

前缀和优化DP

LeetCode3251 单调数组对数目 本题的子问题是下标 0 到 i 中的单调数组对的个数&#xff0c;且 arr1​[i]j&#xff0c;将其记作 f[i][j]。 class Solution { public:int countOfPairs(vector<int>& nums) {const int mod1e97;int nnums.size();int mnums[0];for(in…

C++(STL)的List解读

目录 list简介 list的几个特性 接口函数 1.默认成员函数 2.迭代器相关函数 3.容量相关的函数 4.成员访问相关的函数 5.modify系列 6.operation系列 7.重载在全局的函数 list简介 Lists are sequence containers that allow constant time insert and erase operation…

【Linux】阻塞信号|信号原理|深入理解捕获信号|内核态|用户态|sigaction|可重入函数|volatile|SIGCHILD|万字详解

目录 ​编辑 一&#xff0c;常见的信号术语 二&#xff0c;信号在内核中的表示 信号标志位 Pending表 Block表 handler表 POSIX.1标准 三&#xff0c;sigset_t 信号集操作函数 sigemptyset sigfillset sigaddset sigdelset sigismember sigprocmask sig…

ISP 代理与住宅代理 – 终极指南

模拟自然的、类似人类的流量可能很麻烦&#xff0c;但对于某些任务&#xff08;如帐户管理或网络自动化&#xff09;&#xff0c;没有它就无法完成。ISP 和住宅代理都可以提供帮助&#xff0c;但您不能盲目购买和部署它们。您需要了解它们的优势&#xff0c;理解它们的弱点&…

买的谷歌游戏账号被删了?如果是企业账号找回来的可能性很小。一个识别谷歌企业号的简单方法

这段时间有几个朋友找到我说&#xff0c;自己买的谷歌账号登录不了&#xff0c;有的是直接提示被删除&#xff0c;问能否恢复。 我了解了一下&#xff0c;发现他们的账号都是购买的企业账号。这种企业账号一旦被管理员删除了是无法恢复的。 特此记录下来&#xff0c;提醒各位…

8月13日笔记

msf补充 使用方法&#xff1a; 进入框架&#xff1a;msfconsole 使用search命令查找相关漏洞&#xff1a;search ms14-058 使用info查看模块信息&#xff1a;info 我们也可以将攻击代码写configure.rc&#xff08;只要是以 .rc 结尾的文件&#xff09;配置文件中&#xff0c;然…

【数学建模】介绍论文书写格式

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;Linux专栏&#xff1a;Linux &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 文章目录 1.论文整体排版2. 标题书写3.摘要书写4.参考文献5.公式编辑5.1 常用公式编辑方法…