You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Angular与Spring Boot的图片上传、展示及数据库取回实现

Angular + Spring Boot 实现 Person 图片上传与展示方案

一、Spring Boot 后端实现

1. 调整 Person 实体类

添加图片字段,用@Lob标注大对象类型,适配数据库存储二进制图片数据:

import jakarta.persistence.*;

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    // 其他Person业务字段...
    
    @Lob
    private byte[] profileImage; // 存储图片二进制数据

    // Getter、Setter方法
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public byte[] getProfileImage() { return profileImage; }
    public void setProfileImage(byte[] profileImage) { this.profileImage = profileImage; }
}

2. 编写 Repository 层

继承JpaRepository实现基础CRUD:

import org.springframework.data.jpa.repository.JpaRepository;

public interface PersonRepository extends JpaRepository<Person, Long> {
}

3. 编写 Service 层

处理图片转换与实体保存逻辑:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;

@Service
public class PersonService {
    @Autowired
    private PersonRepository personRepository;

    public Person savePersonWithImage(String name, MultipartFile image) throws IOException {
        Person person = new Person();
        person.setName(name);
        if (image != null && !image.isEmpty()) {
            person.setProfileImage(image.getBytes());
        }
        return personRepository.save(person);
    }

    public byte[] getPersonImageById(Long id) {
        return personRepository.findById(id)
                .map(Person::getProfileImage)
                .orElse(null);
    }
}

4. 编写 Controller 层

提供上传和图片获取接口:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;

@RestController
@RequestMapping("/api/persons")
public class PersonController {
    @Autowired
    private PersonService personService;

    // 上传Person信息与图片
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<Person> uploadPerson(
            @RequestParam("name") String name,
            @RequestParam("profileImage") MultipartFile profileImage) throws IOException {
        Person savedPerson = personService.savePersonWithImage(name, profileImage);
        return new ResponseEntity<>(savedPerson, HttpStatus.CREATED);
    }

    // 根据ID获取图片,用于前端展示
    @GetMapping("/{id}/image")
    public ResponseEntity<byte[]> getPersonImage(@PathVariable Long id) {
        byte[] imageBytes = personService.getPersonImageById(id);
        if (imageBytes == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG); // 可根据实际图片类型调整
        return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
    }
}

5. 配置文件调整

在application.properties中设置文件上传大小限制:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

二、Angular 前端实现

1. 上传组件模板(person-upload.component.html)

<form (ngSubmit)="onSubmit()" #personForm="ngForm">
  <div>
    <label>姓名:</label>
    <input type="text" name="name" [(ngModel)]="personName" required>
  </div>
  <div>
    <label>头像:</label>
    <input type="file" accept="image/*" (change)="onFileSelected($event)">
  </div>
  <button type="submit" [disabled]="!personForm.valid || !selectedFile">提交</button>
</form>

<!-- 图片预览 -->
<div *ngIf="previewUrl">
  <h3>预览:</h3>
  <img [src]="previewUrl" alt="Person Image" style="width: 200px;">
</div>

2. 上传组件逻辑(person-upload.component.ts)

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-person-upload',
  templateUrl: './person-upload.component.html',
  styleUrls: ['./person-upload.component.css']
})
export class PersonUploadComponent {
  personName: string = '';
  selectedFile: File | null = null;
  previewUrl: string | null = null;

  constructor(private http: HttpClient) {}

  onFileSelected(event: any) {
    this.selectedFile = event.target.files[0];
    if (this.selectedFile) {
      this.previewUrl = URL.createObjectURL(this.selectedFile);
    }
  }

  onSubmit() {
    if (!this.selectedFile || !this.personName) return;

    const formData = new FormData();
    formData.append('name', this.personName);
    formData.append('profileImage', this.selectedFile);

    this.http.post('http://localhost:8080/api/persons', formData)
      .subscribe({
        next: (res) => {
          console.log('上传成功', res);
          // 可添加上传成功后的逻辑,如跳转列表页
        },
        error: (err) => {
          console.error('上传失败', err);
        }
      });
  }
}

3. 图片展示组件(person-image.component.ts)

直接调用后端接口展示图片:

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-person-image',
  template: `<img [src]="imageUrl" alt="Person Profile" style="width: 200px;">`
})
export class PersonImageComponent implements OnInit {
  @Input() personId: number | null = null;
  imageUrl: string | null = null;

  ngOnInit() {
    if (this.personId) {
      this.imageUrl = `http://localhost:8080/api/persons/${this.personId}/image`;
    }
  }
}

4. 模块配置(app.module.ts)

确保导入必要模块:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { PersonUploadComponent } from './person-upload/person-upload.component';
import { PersonImageComponent } from './person-image/person-image.component';

@NgModule({
  declarations: [
    AppComponent,
    PersonUploadComponent,
    PersonImageComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

内容的提问来源于stack exchange,提问作者prabin chand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:50:15