选用的基础镜像
python:3.11
python:3.11-slim
python:3.11-alpine

alpine对PaddlePaddle不兼容

复制文件到 /app 文件夹下面

docker里面每一行命令都是基于前一个命令执行之后的容器文件新开一个容器

使用WORKDIR可以将后面的容器目录cd到该目录后面

opencv系统依赖

# 安装OpenCV依赖的系统库
RUN apt-get update && apt-get install -y \
    libgl1  \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libgomp1 \
    libjpeg-dev \
    libpng-dev \
    libtiff-dev \
    libwebp-dev \
    && rm -rf /var/lib/apt/lists/*

关键依赖解释:

  • libgl1 - OpenGL支持(GUI功能)
  • libglib2.0-0 - GLib库
  • libsm6, libxext6, libxrender-dev - X11图形库
  • libgomp1 - OpenMP并行计算
  • libgtk-3-dev - GTK库(GUI界面)
  • libavcodec-dev, libavformat-dev, libswscale-dev - 视频编解码库
  • libjpeg-dev, libpng-dev, libtiff-dev, libwebp-dev - 图像格式支持

最小化安装(如果不需要GUI功能):

RUN apt-get update && apt-get install -y \
    libgl1 \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libgomp1 \
    && rm -rf /var/lib/apt/lists/*

可以先创建虚拟环境,然后用
然后安装一下需要的包,最好使用

pip freeze > requirements.txt

保存下依赖

之后在dockerfile里面可以在copy完之后将依赖下载一下
最后可以使用CMD命令作为启动容器的默认命令,来起一个程序

使用

docker build -t name:tag .

来构建镜像
使用

docker images

来查看镜像
使用

docker run -d -p port:port --name name image:tag

来启动镜像

常用参数:

  • -d:后台运行
  • -p 8000:8000:端口映射(主机端口:容器端口)
  • --name my-container:给容器命名
  • -v /host/path:/container/path:挂载目录
  • -e ENV_VAR=value:设置环境变量

示例:

FROM python:3.11-slim

COPY . /app

WORKDIR /app

# 安装opencv依赖系统库
RUN apt-get update && apt-get install -y \
    libgl1 \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libgomp1 \
    libjpeg-dev \
    libpng-dev \
    libtiff-dev \
    libwebp-dev \
    && rm -rf /var/lib/apt/lists/*

RUN pip install -r requirements.txt

EXPOSE 18689

CMD ["python", "ocr_service.py"]
FROM python:3.11-slim

COPY . /app

WORKDIR /app

RUN pip install -r requirements.txt

EXPOSE 7373

CMD ["python", "main.py"]

先是看下pom.xml里面的java版本,然后选择基础镜像

# 官方OpenJDK镜像(推荐)
FROM openjdk:17-jdk-slim
FROM openjdk:11-jdk-slim
FROM openjdk:8-jdk-slim

# Eclipse Temurin(更好的性能)
FROM eclipse-temurin:17-jdk
FROM eclipse-temurin:11-jdk

可以使用多阶段构建
如果源路径为文件夹,复制的时候不是直接复制该文件夹,而是将文件夹中的内容复制到目标路径。

使用

FROM maven:3.8.5-openjdk-17 AS builder

作为构建jar包时的镜像
https://hub.docker.com/_/maven/tags
这里可以搜索一下tag,主要就是看下jdk版本。

后面使用

FROM openjdk:17-jdk-slim

作为运行环境
两个镜像分隔,可以使最后的的最终镜像大小变小

可以使用

COPY --from=builder

复制前一阶段的文件

如果使用springboot插件需要删除<skip>true</skip>
这个会使SpringBoot插件跳过打包过程
导致没有main-class,运行jar包时报错

no main manifest attribute, in /app/xxx.jar

示例:

FROM maven:3.8.5-openjdk-17 AS builder

COPY . ./app

WORKDIR /app

RUN mvn clean package -DskipTests

FROM openjdk:17-jdk-slim

COPY --from=builder /app/target/xxx-0.0.1-SNAPSHOT.jar /app/xxx.jar

EXPOSE 8080

CMD ["java", "-jar", "/app/xxx.jar"]

基本语法

每个 @RequestParam 都可以单独设置 defaultValue 属性:
例程:

package com.example.demo;

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

@RestController
public class testController {
    // 多个参数,都有默认值
    @RequestMapping("/test")
    public String test(
            @RequestParam(value = "name", defaultValue = "World") String name,
            @RequestParam(value = "age", defaultValue = "18") Integer age,
            @RequestParam(value = "city", defaultValue = "Beijing") String city) {
        return String.format("Hello %s, age %d, from %s", name, age, city);
    }
    
    // 简化写法(参数名与变量名相同时)
    @RequestMapping("/test2")
    public String test2(
            @RequestParam(defaultValue = "Guest") String name,
            @RequestParam(defaultValue = "0") Integer score) {
        return String.format("User: %s, Score: %d", name, score);
    }
}

详细说明

1. 完整写法

@RequestParam(value = "参数名", defaultValue = "默认值") 数据类型 变量名

2. 简化写法(当参数名与变量名相同)

@RequestParam(defaultValue = "默认值") 数据类型 变量名

实际使用示例

// 搜索接口示例
@RequestMapping("/search")
public String search(
        @RequestParam(defaultValue = "") String keyword,           // 搜索关键词,默认空
        @RequestParam(defaultValue = "1") Integer page,            // 页码,默认第1页
        @RequestParam(defaultValue = "10") Integer size,           // 每页大小,默认10条
        @RequestParam(defaultValue = "createTime") String sortBy,  // 排序字段,默认按创建时间
        @RequestParam(defaultValue = "desc") String sortOrder) {   // 排序方向,默认降序
    
    return String.format("搜索: %s, 第%d页, 每页%d条, 按%s %s排序", 
                        keyword, page, size, sortBy, sortOrder);
}

// 用户信息接口示例
@RequestMapping("/userInfo")
public String getUserInfo(
        @RequestParam(defaultValue = "0") Long userId,
        @RequestParam(defaultValue = "false") Boolean includeDetails,
        @RequestParam(defaultValue = "json") String format) {
    
    return String.format("用户ID: %d, 包含详情: %s, 格式: %s", 
                        userId, includeDetails, format);
}

注意事项

  1. 数据类型转换:Spring会自动进行类型转换
  2. 必需参数:如果不设置 defaultValue,参数就是必需的
  3. 可选参数:设置了 defaultValue 的参数变为可选
  4. 布尔值默认值"true""false"(字符串形式)
  5. 数字默认值:用字符串表示,如 "0""100"

进阶用法

@RequestMapping("/advanced")
public String advanced(
        @RequestParam(value = "q", defaultValue = "") String query,
        @RequestParam(defaultValue = "1") @Min(1) Integer page,
        @RequestParam(defaultValue = "10") @Range(min = 1, max = 100) Integer size,
        @RequestParam(required = false) String category,  // 可选参数,无默认值时为null
        @RequestParam(defaultValue = "false") Boolean exact) {
    
    // 处理逻辑
    return "搜索结果";
}

如何修改端口

要修改Web服务器端口,只需在 application.properties 文件中添加以下配置:

spring.application.name=demo
server.port=8081

常用端口配置示例

# 修改为8081端口
server.port=8081

# 修改为9000端口
server.port=9000

# 修改为3000端口(常用于前端开发)
server.port=3000

# 使用随机端口(测试时有用)
server.port=0

其他相关配置

还可以配置其他服务器相关属性:

# 端口配置
server.port=8081

# 上下文路径(访问路径前缀)
server.servlet.context-path=/api

# 服务器地址(默认为所有接口)
server.address=localhost

# 会话超时时间
server.servlet.session.timeout=30m

1. @RequestBody 的作用

@RequestBody 注解用于将HTTP请求体中的JSON数据自动映射到Java对象。Spring Boot会自动处理这个转换过程。

2. 自动映射机制

Spring Boot使用Jackson库(默认的JSON处理器)来完成JSON到Java对象的转换:

  1. 序列化:Java对象 → JSON(响应时)
  2. 反序列化:JSON → Java对象(请求时,@RequestBody的作用)

3. 如何编写接收类(DTO/Entity)

基本要求:

  • 使用类(Class)
  • 提供无参构造函数
  • 提供getter/setter方法(或使用Lombok)
  • 字段名要与JSON中的key对应

示例代码:

// 方式1:传统写法
public class User {
    private String name;
    private Integer age;
    private String email;
    
    // 无参构造函数(必需)
    public User() {}
    
    // 有参构造函数(可选)
    public User(String name, Integer age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
    
    // Getter和Setter方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

// 方式2:使用Lombok(推荐)
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Data  // 自动生成getter/setter/toString/equals/hashCode
@NoArgsConstructor  // 无参构造函数
@AllArgsConstructor // 全参构造函数
public class User {
    private String name;
    private Integer age;
    private String email;
}

tip:
如果想要使用Lombok,需要在pom.xml中写入依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

4. Controller中的使用

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        // Spring自动将JSON转换为User对象
        System.out.println("接收到用户:" + user.getName());
        
        // 处理业务逻辑
        User savedUser = userService.save(user);
        
        return ResponseEntity.ok(savedUser);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(
            @PathVariable Long id, 
            @RequestBody User user) {
        User updatedUser = userService.update(id, user);
        return ResponseEntity.ok(updatedUser);
    }
}

5. JSON映射示例

前端发送的JSON:

{
    "name": "张三",
    "age": 25,
    "email": "[email protected]"
}

自动映射到User对象:

User user = new User();
user.setName("张三");
user.setAge(25);
user.setEmail("[email protected]");

6. 高级特性

字段验证:

import javax.validation.constraints.*;

public class UserCreateDTO {
    @NotBlank(message = "姓名不能为空")
    @Size(min = 2, max = 50, message = "姓名长度必须在2-50之间")
    private String name;
    
    @NotNull(message = "年龄不能为空")
    @Min(value = 0, message = "年龄不能为负数")
    @Max(value = 150, message = "年龄不能超过150")
    private Integer age;
    
    @Email(message = "邮箱格式不正确")
    private String email;
}

// Controller中启用验证
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateDTO dto) {
    // 如果验证失败,Spring会自动返回400错误
    return ResponseEntity.ok(userService.create(dto));
}

JSON字段映射:

import com.fasterxml.jackson.annotation.JsonProperty;

public class UserDTO {
    @JsonProperty("user_name")  // JSON中的字段名
    private String name;        // Java中的字段名
    
    @JsonProperty("user_age")
    private Integer age;
}