Spring Boot基础

项目创建

项目启动

请求响应

RestController

1.返回值处理

@RestController:这个注解结合了@Controller和@ResponseBody的功能。它默认将所有处理请求的方法的返回值直接作为响应体内容返回,主要用于构建RESTful API。返回的数据格式通常是JSON或XML,这取决于请求中的Accept头部或配置的消息转换器。

Controller:这个注解的返回值通常会经过视图解析器解析,然后返回给用户一个渲染后的HTML页面。如果需要在Controller中返回JSON或XML数据,需要在方法上额外添加@ResponseBody注解。

  1. 用途和场景

@RestController:主要用于构建RESTful Web服务,它简化了开发RESTful风格的控制器的代码,使得开发者能够更加专注于业务逻辑的实现,而无需关注底层的请求-响应处理细节。它支持get、post、put、delete等HTTP方法,适用于前后端分离的架构。

@Controller:更多地与视图渲染和页面跳转相关,适用于传统的MVC(Model-View-Controller)架构。通过页面模板引擎(如JSP、Thymeleaf等)将数据渲染成HTML页面返回给用户。

创建 HelloController.java

java 复制代码
package org.example.myspringboot;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

// @RequestMapping("/api")
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }
}

请求 http://127.0.0.1:8080/hello 访问接口

增加 @RequestMapping("/api") 访问变成:http://127.0.0.1:8080/api/hello

RequestMapping

参数:

  • value 路由 默认 /

  • method 请求方式:默认GET
    RequestMethod.GET,RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE

    java 复制代码
        @RequestMapping(value = "/hello", method = RequestMethod.DELETE)

RequestParam

@RequestParam注解用于将HTTP请求中的参数绑定到方法的参数上

参数:

  • value 获取的字段名
  • required 字段值是否为必须,false为非必须
  • defaultValue 字段默认值

例如url: http://127.0.0.1:8080/api/hello?name=xx ,获取name的值

java 复制代码
package org.example.myspringboot;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/api")
@RestController
public class HelloController {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello(@RequestParam(value = "name", required = false, defaultValue = "Alex") String name) {
        System.out.println(name);
        return "hello";
    }
}

处理多个参数

http://127.0.0.1:8080/api/hello?name=xx&age=18

java 复制代码
package org.example.myspringboot;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


@RequestMapping("/api")
@RestController
public class HelloController {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello(
            @RequestParam(value = "name") String name,
            @RequestParam(value = "age") Integer age
    ) {
        System.out.println(name + " " + age);
        return "hello";
    }
}

使用Map处理多个参数

java 复制代码
package org.example.myspringboot;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;


@RequestMapping("/api")
@RestController
public class HelloController {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello(Map<String, String> params) {
        String name = params.get("name");
        String age = params.get("age");
        System.out.println(name + " " + age);
        return "hello";
    }
}

使用List处理多个相同参数

http://127.0.0.1:8080/api/hello?name=xx&name=yy

java 复制代码
package org.example.myspringboot;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;


@RequestMapping("/api")
@RestController
public class HelloController {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello(@RequestParam List<String> name) {
        System.out.println(name);
        return "hello";
    }
}

PathVariable

@PathVariable注解获取url中的参数

http://127.0.0.1:8080/api/hello/100/Alex

java 复制代码
package org.example.myspringboot;

import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;


@RequestMapping("/api")
@RestController
public class HelloController {
    @RequestMapping(value = "/hello/{id}/{name}", method = RequestMethod.GET)
    public String hello(@PathVariable String id, @PathVariable String name) {
        System.out.println(id);
        System.out.println(name);
        return "hello";
    }
}

RequestBody

@RequestBody注解:将JSON数据映射到形参的实体类对象中(JSON中的key和实体类中的属性名保持一致)

java 复制代码
package org.example.myspringboot;

import org.springframework.web.bind.annotation.*;

@RestController
public class DataController {

    public static class Address{
        public String street;
        public String city;

//        public Address() {} // 添加无参构造函数
    }

    public static class User{
        public Integer id;
        public String name;
        public Integer age;
        public Address address;

//        public User() {}  // 添加无参构造函数
    }

    @RequestMapping(value = "user/{id}", method = {RequestMethod.POST, RequestMethod.GET})
    public String data(@RequestBody User user, @PathVariable Integer id){
        System.out.println(user.name);
        return "Hello World";
    }
}
复制代码
@RequestBody User user 可以将 请求体中json数据映射到 User中

上传文件

java 复制代码
package org.example.myspringboot;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.awt.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@RestController
public class FilesController {

    private static final String UPLOAD_PATH = "uploads" ;

    @RequestMapping(value = "file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String files(@RequestParam("file") MultipartFile file) {
        try {
            Path uploadPath = Paths.get(UPLOAD_PATH);
            // 路径是否存在,不存在创建
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
            String fileName = file.getOriginalFilename();
            // 保存文件
            Files.copy(file.getInputStream(), uploadPath.resolve(fileName));
            return UPLOAD_PATH + "/" + fileName;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "上传失败";
    }
}
复制代码
private static final String UPLOAD_PATH = "uploads";

UPLOAD_DIR 是一个静态常量,其值为 "uploads"。这个变量用来指示文件上传的目标目录。让我们详细解释一下这段代码及其各个部分的意义:

常量定义

  • private: 这个关键字表示这个变量只能在定义它的类内部被访问。这是封装的一个体现,有助于保护数据不被外部直接修改。
  • static: 表示这是一个静态变量,即它是属于类的而不是实例的。这意味着所有该类的实例都将共享同一个UPLOAD_DIR的值。
  • final: 这个关键字表示这个变量是最终的,不可改变的。一旦赋值,就不能再重新赋值。在这个场景中,我们希望上传目录的路径是一次性设定好的,并且在整个应用程序运行期间保持不变。

作用

  1. 路径确定性: 使用常量可以确保上传目录的路径在应用启动时就被确定下来,这样每次上传操作都能知道文件应该保存在哪里。
  2. 可维护性: 如果将来需要更改上传目录,只需要修改这一个地方即可,不需要在整个应用中搜索并替换所有的路径字符串。
  3. 易读性和易理解: 声明为常量使得其他开发人员更容易理解这个字符串是用来做什么的,同时也使得代码更加清晰和易于维护。

使用final关键字有几个好处:

  1. 不可变性: 它保证了一旦给定一个值之后,这个值就不会被改变。这对于配置信息特别有用,因为配置项通常是固定的,在程序运行期间不应该改变。
  2. 线程安全性 : 在多线程环境下,final变量提供了天然的可见性保证,因为它们在初始化后不会被修改,所有线程看到的都是相同的值。
  3. 性能优化 : 编译器和JVM能够对final字段进行一些优化,因为它们知道这些字段的值不会改变。
consumes = MediaType.MULTIPART_FORM_DATA_VALUE

consumes属性的作用

consumes属性用于指定该方法能够消费(接受)哪种类型的HTTP请求体内容。这里MediaType.MULTIPART_FORM_DATA_VALUE指定了该方法期望接收的数据类型为multipart/form-data,这是一种常见的用于上传文件的媒体类型。

  • 指定支持的媒体类型consumes属性告诉Spring MVC框架,只有当请求的内容类型(Content-Type)与consumes指定的媒体类型匹配时,才会调用该方法来处理请求。
  • 消息转换器 :Spring MVC使用消息转换器(Message Converters)来读取和写入请求/响应体。对于multipart/form-data类型的数据,Spring默认使用CommonsMultipartResolver或者StandardServletMultipartResolver来解析这类请求。
  • 自动绑定 :当consumes指定为MediaType.MULTIPART_FORM_DATA_VALUE时,Spring可以自动将请求体中的数据绑定到方法参数上。例如,@RequestParam用于获取普通表单字段的值,而@RequestParam("file") MultipartFile则用于接收上传的文件
MultipartFile file

MultipartFile是一个特殊的类型,它扩展了Part接口,并且专门用于处理上传的文件。MultipartFile提供了访问上传文件的方法,如获取文件名、文件类型、读取文件内容等。

@RequestParam("file") MultipartFile file这一行代码的意思是:

  • @RequestParam("file"):这表明HTTP请求中必须包含一个名为"file"的参数。这个参数通常是由HTML表单中的<input type="file" name="file">标签发送过来的。
  • MultipartFile file:这个参数类型表明这个方法期望接收到的是一个上传的文件。Spring MVC会将"file"参数对应的文件内容封装成一个MultipartFile对象,并传递给这个方法参数。

下载文件

java 复制代码
package org.example.myspringboot;

import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@RestController
public class FilesController {

    private static final String UPLOAD_PATH = "/Users/apple/Downloads";


    @GetMapping("file/{fileName}/download")
    public ResponseEntity<InputStreamResource> downloadFile(@PathVariable String fileName) throws IOException {
        Path path = Paths.get(UPLOAD_PATH + "/" + fileName);
        if (!Files.exists(path)) {
            return ResponseEntity.notFound().build();
        }
        File file = new File(String.valueOf(path));
        InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"");
        headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");
        return ResponseEntity.ok().headers(headers).body(resource);
    }

    @RequestMapping("file/{fileName}/preview")
    public ResponseEntity<Resource> previewFile(@PathVariable String fileName) throws IOException {
        Path path = Paths.get(UPLOAD_PATH + "/" + fileName);
        Resource imageFile = new UrlResource(path.toUri());
        if (!imageFile.exists() && !imageFile.isReadable()) {
            return ResponseEntity.notFound().build();
        }
        String contentType = Files.probeContentType(path);
        if (contentType == null) {
            return ResponseEntity.notFound().build();
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType(contentType));
        return ResponseEntity.ok().headers(headers).body(imageFile);
    }
}

返回静态页面

java 复制代码
package org.example.myspringboot;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController {
    @RequestMapping
    public String index() {
        return "/index.html";
    }
}

ResponseBody

@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据

ResponseEntity

ResponseEntity可以更灵活地处理HTTP响应,而不仅仅局限于返回简单的数据类型

返回string

java 复制代码
    @RequestMapping(value = "user", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity<String> data(){
        System.out.println(user.name);
        return ResponseEntity.ok()
                .header("Content-Type", "application/json")
                .body("提交成功");
    }

返回自定义类型

java 复制代码
package org.example.myspringboot;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class DataController {

    public static class Address{
        public String street;
        public String city;
    }

    public static class User{
        public Integer id;
        public String name;
        public Integer age;
        public Address address;
    }

    @RequestMapping(value = "user/{id}", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity<User> data(@RequestBody User user, @PathVariable Integer id){
        System.out.println(user.name);
        return ResponseEntity.ok()
                .header("Content-Type", "application/json")
                .body(user);
    }
}

设置响应状态码

java 复制代码
    @RequestMapping(value = "user", method = {RequestMethod.POST, RequestMethod.GET})
    public ResponseEntity<String> data(){
        System.out.println(user.name);
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .header("Content-Type", "application/json")
                .body("未来找到数据");
    }

参考

Java Spring Boot 全面教程_java springboot-CSDN博客

相关推荐
腾渊信息科技公司14 分钟前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地1 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
憧憬成为web高手1 小时前
皮卡丘靶场速通--sql 2
数据库·sql·mybatis
段一凡-华北理工大学1 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
oradh3 小时前
Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)
数据库·oracle·11g升级19c·xtts跨版本迁移和升级
莫逸风4 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
隔窗听雨眠4 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
z123456789864 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
程序猿DD4 小时前
一个 API Key,统一调用大模型、生图和联网搜索
数据库·网关
yaoxin5211235 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python