Spring MVC和Spring Boot

news2024/12/23 12:49:20

上节已经提到过请求,这次梳理响应。

响应

响应基本上都要被@Controller所托管,告诉Spring帮我们管理这个代码,我们在后面需要访问时,才可以进行访问,否则将会报错。并且其是由@RestController分离出来的,@RestController分离出来了@Controller来返回视图,随着现在前后端的彻底分离,现在返回视图所需要的数据,还分离出@RestponseBody来进行返回数据。

1.返回静态页面

@Controller进行对其的托管,并且这个注解只能修饰类,Spring 容器会将其实例化并管理起来,使得它可以接收并处理客户端的请求,并且一般负责负责接收和处理 HTTP 请求,调用业务逻辑完成业务处理,生成视图并返回给客户端,处理异常情况等。

切记在return的后面加上/来确保其是以url的格式 进行返回

@Controller
public class text {

    @RequestMapping("index")
    public String teturnIndex(){

        return "/index.html";
    }
}

在响应不加@Controller进行托管,直接就会报错

2.返回数据

@RestsponseBody注解来进行修饰,可以修饰类和方法,修饰类时表示这个类下的所有方法返回的都是数据,修饰方法时,表示该方法返回的是数据。所以如果一个类的所有方法都是返回数据直接加到类上,避免重复性操作。

@ResponseBody
    @RequestMapping("/returnData")
    public  String returnData(){
        return "返回数据";
    }

3.返回html的代码片段

@RestsponseBody注解来进行修饰

   @ResponseBody
   @RequestMapping("/returnHtml")
    public  String returnHtml(){
        return "<input type=\"button\" value=\"提交\" id=\"checkCaptcha\">";
    }

4.返回JSON

当我们的接口返回的是String时, content-Type是text/html
 

    @ResponseBody
    @RequestMapping("/returnHtml2")
    public  String returnHtml2(){
        String name = "zhangsan";
        return  name;
    }

当我们的接口返回的是对象时, content-type自动设置为application/json Map

    @ResponseBody
    @RequestMapping("/returnJson")
    public  Person returnJson(){
        Person person = new Person();
        person.setAge(12);
        person.setName("zhangsan");
        return person;
    }

5.返回设置状态码

    @ResponseBody
    @RequestMapping("/setStatus")
    public  String setStatus(HttpServletResponse response){
        response.setStatus(404);
        return  "设置状态码";
    }

6.设置Header 

默认是返回html,可以改成json。但是还需要匹配,不匹配仍然报错。

 consume:限制响应的提交内容类型(Content-Type),例如applicationljson, text/html;,如果指定application/sor
produces:设置返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
(???)在哪里用到了

    @ResponseBody
    //@RequestMapping(value = "r1")不设置返回类型默认html
    @RequestMapping(value = "/r1",produces = "application/json; charset=utf-8")//设置返回类型Json,但仍然需要匹配
    public  String r1(HttpServletResponse response){

        return  "{'ok':1}";
    }

三层架构

三层架构主要将程序代码分为三个部分来进行分别书写,减少代码的耦合性,将应用程序分为表示层、业务逻辑层和数据访问层,每一层都有明确定义的责任,彼此不互相干扰。

1.表现层:接收请求,返回结果业务
2.业务逻辑层:主要处理业务逻辑

3.数据层:处理数据,包含数据的存储,获取(增删改查)

在代码中一般将其三层放在这三个对应的包内

Controller:接收请求,参数是否合法,结果响应

Service:处理请求(主要干活的部分)
Dao:数据部分(将数据从数据库中取处理让Service进行处理)

MVC注重数据和视图的分离。

三层架构注重从不同方向上取处理。

两者都是为了更好书写的代码,将代码通过自己的思想将不同的部分进行分离出来,使最终写成的程序可以有更好的可维护性,扩展性等。二者在进行一个系统设计时可以分别使用,也可以一起使用。

例如一起使用时,可以将MVC中的视图作为表示层的实现,将控制器作为业务逻辑层的门面,将模型作为业务逻辑层的实现。这样做的好处是可以更加紧密地结合业务逻辑和用户界面,提高系统的开发效率和可维护性。

例如分别使用时,可以首先设计并实现三层架构,将系统分为表示层、业务逻辑层和数据访问层,然后在每一层中使用MVC进行设计和实现。这样做的好处是可以更加清晰地分离不同层次的责任,使系统的架构更加模块化和灵活。

注:

命名建议
大驼峰: BookDao
类名使用大驼峰
小驼峰: bookDao
变量名小驼峰
蛇形: book_dao
数据库,字段命名用蛇形
串形: book-dao

 

Spring的核心思想之一IOC
 

Spring是一个包含众多工具的loC容器
容器就是用来存储各种数据的东西。

list/map装各种数据类型的容器
tomcat装web的容器
Spring容器,装的是对象

Spring容器中存的是对象,对象这个词,在Spring的范围内,称之为bean

loC:控制反转(控制权反转)就是创建对象的控制权,交给了Spring。

例如下面代码中,如果想要让这个车能正常行驶起来行驶,并且想要生产不同的车轮大小,需要将在最开始就将车轮胎的代码传输过去,其耦合性极高,中间一个代码出现问题,全寄。

class Car {
    private Framework framework;

    public Car(int size) {
        framework = new Framework(size);
        System.out.println( "car init. .. ");
    }
    public void run() {
        System.out.println( "car run. . . ");
    }
}
class Framework {
    private Bottom bottom;
    public Framework(int size) {
        bottom = new Bottom(size);
        System.out.println( "framework init. . .." );
    }
}

class Bottom {
    private Tire tire;
    public Bottom(int size) {
        tire = new Tire(size);
        System.out.println("bottom init.. ." );
    }
}
class Tire {
    private int size;
    public Tire(int size) {
        this.size = size;
        System.out.println("tire init. . .size : "+size);
    }
}

所以这样进行设计就可以将生产汽车的各个组件隔离开来,哪里发生问题即刻就可以知道。减少了其耦合。一个寄不会全寄。


class Car {
    private Framework framework;
    public Car() {

        framework = new Framework();
        System.out.println( "car init. . . " );
    }
    public void run() {
        System.out.println( "car run. . ." );
    }
}
class Framework {
    private Bottom bottom;

    public Framework(){
        bottom = new Bottom();
        System.out.println( "framework init. . .. " );
    }
}
class Bottom {
    private Tire tire;
    public Bottom() {
        tire = new Tire();
        System.out.println( "bottom init. .. " );
    }
}
class Tire {
    private int size = 21;
    public Tire() {
        System.out.println( "tire init. . ."+size );
    }
}


Spring帮我们管理对象
1.告诉Spring,帮我们管理哪些对象 (存)
2.知道如何取出来这些对象(取)

Spring的loC思想实现了这种事情,通过DI最终来进行了实现。

DI把依赖对象取出来,并在DI实现的这个类中直接赋给该对象的属性

下面代码就进行了实现,可以看到要在一个类中使用另外一个类时,使用@Autowired这样的注解就不用在重复性的在这个类中去创建对象了。直接去使用。


@Component
@Data//可以不写setter和getter等创建类时的重复性操作
class Student {//存到Spring中

    private  String name;

    private  Integer age;
    // 添加构造函数和 getter、setter 方法

}

@Controller
 class StudentCard {

    @Autowired
    private Student student;//从Spring中去取,

    public void text() {
        // 可以在这里使用注入的 student 对象
        System.out.println("Student name: " + student.getName());
        System.out.println("Student age: " + student.getAge());
    }

}

DI的具体实现依靠于两大注解类型

存注解:

类注解@Controller、@Service、@Repository、@Component、@Configuration.

方法注解@Bean

取注解:@Autowired@Resource@Qualifier@Inject@value 

取注解一般使用@Autowired

Spring上下文

Spring上下文和DI的实现是紧密相关的,Spring上下文作为DI的实现载体,负责管理Bean之间的依赖关系,从而实现了IoC容器的功能。具体来说Spring上下文负责创建、管理和组织应用程序中的Bean,它会根据Bean之间的依赖关系,在需要的时候将依赖注入到相应的对象中。通过DI机制,Spring上下文实现了控制反转,将对象的创建和管理交给了Spring容器。

@controller注解的作用

从context中获取类的对象,@controller将类存入Spring之后就被称为bean对象。

通过getBean来获取我们的类的对象。,并且通过这个对象去访问类中的方法。

        ApplicationContext context = SpringApplication.run(Demo9Application.class,args);
        Student bean = context.getBean(Student.class);
        bean.student();

但是如果Student类中如果没有@Controller则是不能取到对象的,错误如下

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo9.Student' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1178)
	at com.example.demo9.Demo9Application.main(Demo9Application.java:13)

@severive也和上面一样,这些存注解,都会将其存入到Spring中,想去取得时候就可以通过getBean来获取我们的类的对象。

@Controller、@Service、@Repository、@Component、@Configuration,这些注解都是component的衍生类或者是他的本身所建立出来的。

但是@Controller是被赋予了一些其他注解没有的功能,其在Spring MVC中具有特殊的作用,它用于标记一个类作为控制器(Controller),用于处理HTTP请求。

以及必需使用@Controller代码的入口才能正常加载,否则会报如下错误

并且上述五大注解只能放类上,只能加在我们自己写的代码上。如果我引入了一个第三方Jar包,也希望交给Spring管理,是没有办法加五大注解。

这些都是针对于一个对象来进行管理,但是如果对于一个类,定义多个对象时,比如数据库操作,定义多个数据源,就需要使用@Bean来进行操作了
Bean是方法注解
@Bean必须搭配五大注解来使用

否则单独使用的话会报如下的错误,大致意思是程序没有找到bean对象。加上五大注解就意外着向Spring容器上传,接下来使用时,就会找到


 

并且使用@bean注解时,bean的名称必需是类名,否则不能找到对应的bean对象。

注:如果需要的Bean的类型,对应的对象只有一个时,就直接赋值如果有多个时,通过名称去匹配

SpringBoot特点;约定大于配置其中之一体现:就是扫描路径

其默认扫描路径是:启动类所在的目录及其子孙目录。但是我们可以通过这个注解可以指定扫描路径@ComponentScan( "com.bite.demo" ),如果没有指定那就是默认路径。

DI的依赖注入

依赖注入总共有三种

1.属性注入2.构造方法注入3.Setter方法注入

@Autowired
private test test;//属性注入



    //Setter方法注入
    @Autowired
    private test test;
    @Autowired
    public getBean(test test){//构造
        this.test = test;
    }

    //构造方法注入
    private  test test;
    @Autowired
    public getBean(test test){
    this.test = test;
    }

都是将存入Spring容器中bean对象放到类中来进行使用。

属性注入以类型进行匹配,与注入的属性名称无关但是如果一个类型存在多个对象时,优先名称匹配,如果名称匹配不上,寄报错。
无法注入一个Final修饰的属性,想要注入1.定义时就进行赋值2.构造方法中进行赋值

如果存在多个构造函数时,需要加@AutoWired注明使用哪个构造函数
如果只有一个构造函数,@AutoWired可以省略掉

属性注入:先将其里面的属性创建成功之后,其才能被创建好

如果里面的属性是被static修饰的话,不用这样

当程序中同一个类型有多个对象时,使用@AutoWired会报错(一些情况下)
解决方法
1.属性名和你需要使用的对象名保持一致

2.使用@Qualifier

@Controller
class UserController4 {
//注入
    @Resource(name = "user1" )
    private User user;
    public User getUser( ){
        return user;
     }
}



3使用@Resource注解

 

@Controller
public class UserController5 {
//注入
    @Autowired
    @Qualifier(value = "user2")
    private User user;
    public User getUser() {
    return user;
    }

}

依赖注入的主要目的之一就是让类能够获取到由Spring容器管理的对象实例或其他依赖项,从而解耦组件之间的关系,不需要知道如何创建它所依赖的对象,只需定义它们所需的接口或抽象类型。

 

@Autowird 与@Resource的区别
@Autowired是spring框架提供的注解,而@Resource是JDK提供的注解
@Autowired 默认是按照类型注入,而@Resource是按照名称注入.相比于@Autowired 来说,@Resource支持更多的参数设置,例如name 设置,根据名称获取 Bean。

Bean的存
使用五大注解和@Bean时, Spring会给一个默认的名称
1.五大注解
五大注解: BeanName是类名的小驼峰表示法(首字母小写)
特殊情况:如果前两位字母都为大写,BeanName为类名

如果在五大注解之中添加名称之后,就会更改五大注解bean的名称,Spring会使用程序员定义的Bean的名称。在启动类中获取对象时需要的就是BeanName。

同理也可以修改@Bean的名称

Bean的取

1.属性注入@AutoWired
⒉.构造方法注入
如果只有一个构造方法,@AutoWired可以省略
3. Setter方法注入

@AutoWired存在问题
同一个类型的存在多个对象时,可能会出错解决思想:指定Bean的名称
指定Bean
1.修改@AutoWired修饰的属性名为需要的Bean的名称
3.使用@Qualifity指定Bean的名称

4.使用@Resource




 


 

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

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

相关文章

【MCU】栈溢出问题

项目场景&#xff1a; 硬件&#xff1a;STM32F407&#xff0c;操作系统&#xff1a;rt_thread master分支 问题描述 问题栈溢出 id 499 ide 00 rtr 00 len 8 9 Function[rt_completion_wait] shall not be used in ISR (0) assertion failed at function:rt_completion_wait,…

MATLAB实现蚁群算法栅格路径优化

蚁群算法是一种模拟自然界中蚂蚁觅食行为的优化算法&#xff0c;常用于解决路径规划问题。在栅格路径优化中&#xff0c;蚁群算法可以帮助找到从起点到终点的最优路径。以下是蚁群算法栅格路径优化的基本流程步骤&#xff1a; 初始化参数&#xff1a; (1)设置蚂蚁数量&#xff…

【错题集-编程题】数组中的最长连续子序列(排序 + 模拟)

牛客对应链接&#xff1a;数组中的最长连续子序列_牛客题霸_牛客网 (nowcoder.com) 一、分析题目 排序 模拟。 注意&#xff1a;值连续&#xff0c;位置可以不连续&#xff01;小心处理数字相同的情况。 二、代码 //值得学习的代码 class Solution { public:int MLS(vecto…

【数据库】Redis

文章目录 [toc]Redis终端操作进入Redis终端Redis服务测试切换仓库 String命令存储字符串普通存储设置存储过期时间批量存储 查询字符串查询单条批量查询 Key命令查询key查询所有根据key首字母查询判断key是否存在查询指定的key对应的value的类型 删除键值对 Hash命令存储hash查…

前端补充17(JS)

一、JS组成成分 JS的组成成分&#xff0c;由三部分组成 第一、ECMAScript&#xff1a;语法规则&#xff0c;如何定义变量&#xff0c;数据类型有哪些&#xff0c;如何转换数据类型&#xff0c;if判断 if-else while for for-in forEach do-while switch 数组 函数 对…

HTML表单(详解网页表单如何实现)

目录 一、表单介绍 1.概念 二、表单用法 1.HTML表单 2.HTML 表单 - 输入元素 2.1.文本域&#xff08;Text Fields&#xff09; 2.2.密码字段 2.3.单选按钮&#xff08;Radio Buttons&#xff09; 2.4.复选框&#xff08;Checkboxes&#xff09; 2.5.提交按钮(Submit)…

SAP 变更记录表查询使用逻辑简介

通常用户在遇到问题后&#xff0c;经常会问某个单据的变更记录&#xff0c;很多模块中在前台的操作界面中都根据对应的菜单栏中可以找到对应的变更记录&#xff0c;像销售订单、交货单、采购申请、采购订单都在菜单栏位中都可以查询到对应的修改记录&#xff0c;但是对于想批量…

“豪门”子刊!中科院2区SCI,收稿范围广,发文量超20000!无预警记录,极速录用见刊!

&#xff08;一&#xff09;期刊简介概况 【期刊类型】网络数据类SCIE 【出版社】SPRINGER出版社 【期刊概况】IF&#xff1a;4.0-5.0&#xff0c;JCR2区&#xff0c;中科院2区 【版面类型】正刊&#xff0c;仅10篇版面 【预警情况】2020-2024年无预警记录 【收录年份】2…

【项目】基于JDBC+MySQL的Java教务管理系统(附源码+论文说明)

摘要 随着信息技术的不断发展&#xff0c;教育管理也在向数字化、智能化方向迈进。Java作为一种广泛应用于企业级应用开发的编程语言&#xff0c;与数据库技术的结合更是为教务管理系统的开发提供了强大的支持。 本文将介绍基于JDBC&#xff08;Java Database Connectivity&a…

跨越未知,拥抱挑战——新征程

在浩瀚的IT领域里&#xff0c;每一位开发工程师都如同一位探险家&#xff0c;不断地探索、挑战和成长。作为一名新入职的Java开发工程师&#xff0c;我面临着全新的技术栈和业务领域&#xff0c;这是一次跨越未知的征程&#xff0c;也是一次自我提升的机会。 新入职 初入公司…

mac系统镜像源管理之nrm的安装与使用

之前有介绍过&#xff1a;pnpm安装和使用&#xff0c;nvm安装及使用&#xff0c;在前端开发中其实还有一个工具也会偶尔用到&#xff0c;那就是nrm&#xff0c;本文就详解介绍一下这个工具&#xff0c;非常的简单且好用&#xff5e; 文章目录 1、什么是nrm&#xff1f;2、安装3…

为什么说这些倒腾AI的方式会把自己“搞死”

在AI技术的浪潮下&#xff0c;许多基于大模型的产品涌现而出&#xff0c;但并非所有创新都能带来成功&#xff0c;有时大模型的出现还会放大AI创业公司的内部矛盾。这个时候&#xff0c;我们需要搭建与AI相配的底层思考框架。 为什么说这些倒腾AI的方式会把自己“搞死”© …

go语言并发实战——日志收集系统(五) 基于go-ini包读取日志收集服务的配置文件

实现日志收集服务的客户端 前言 从这篇文章开始我们就正式进入了日志收集系统的编写&#xff0c;后面几篇文章我们将学习到如何编写日志收集服务的客户端,话不多说,让我们进入今天的内容吧&#xff01; 需要实现的功能 我们要收集指定目录下的日志文件&#xff0c;将它们发…

Flink CDC详解

文章目录 Flink CDC一 CDC简介1.1 CDC定义1.2 CDC应用场景1.3 CDC实现机制1.4 开源CDC工具对比 二 Flink CDC简介2.1 Flink CDC介绍2.2 Flink CDC Connector(连接器)2.3 Flink CDC && Flink版本2.4 Flink CDC特点 三 Flink CDC发展3.1 发展历程3.2 背景Dynamic Table &…

Ubuntu镜像下载与安装2024.4版本(超适合新手)

前言&#xff1a; 在VMware中安装Ubuntu镜像&#xff0c;首先需要去下载镜像&#xff0c;但是由于服务器在国外&#xff0c;下载速度相对较慢&#xff0c;国内也有镜像&#xff0c;较推荐在国内镜像站下载&#xff0c;例如阿里镜像和清华镜像。 官网&#xff1a;Ubuntu系统下…

LLM 为什么需要 tokenizer?

文章目录 1. LLM 预训练目的1.1 什么是语言模型 2. Tokenizer一般处理流程&#xff08;了解&#xff09;3. 进行 Tokenizer 的原因3.1 one-hot 的问题3.2 词嵌入 1. LLM 预训练目的 我们必须知道一个预训练目的&#xff1a;LLM 的预训练是为了建立语言模型。 1.1 什么是语言模…

月入8k,21岁计算机专业男孩转行网优,天赋可以让人发光,努力也能!

今天的主人公是一位仅21岁的年轻小帅哥&#xff0c;大学学的是计算机专业&#xff0c;毕业后的工作是卖苦力&#xff0c;工作一段时间后毅然决然的选择了转行后台网优&#xff0c;让我们一起来看看这位21岁男孩转行背后的故事... 卖苦力&#xff0c;是没有前途的 今天的主人公…

(一)JVM实战——jvm的组成部分详解

前言 本节内容是关于java虚拟机JVM组成部分的介绍&#xff0c;通过其组成架构图了解JVM的主要组成部分。 正文 ClassFile&#xff1a;字节码文件 - javac&#xff1a;javac前端编译器将源代码编译成符合jvm规范的.class文件&#xff0c;即字节码文件 - class文件的结构组成&a…

Springboot的日常操作技巧

文章目录 1、自定义横幅2、容器刷新后触发方法自定义3、容器启动后触发方法自定义**CommandLineRunner**ApplicationRunner 不定时增加 参考文章 1、自定义横幅 简单就一点你需要把banner.text放到classpath 路径下 &#xff0c;默认它会找叫做banner的文件&#xff0c;各种格式…

[GXYCTF2019]BabyUpload-BUUTF

题&#xff1a; 步骤&#xff08;先上传木马&#xff0c;在上传.htaccess&#xff09; 准备工作 他过滤了<? ,ph等 准备&#xff1a;一句话木马&#xff0c;.htaccess文件 .htaccess SetHandler application/x-httpd-php //解析为php文件 muma1.jpg<script languag…