3.4

一、后端图片服务设计
在 Spring Boot 中实现图片上传接口,使用 MultipartFile 接收文件流,并存储到本地或云存储:
java
// 图片上传控制器
@RestController
@RequestMapping("/api/image")
public class ImageController {
private final String uploadDir = "D:/uploads/"; // 本地存储路径

@PostMapping("/upload")
public ResponseEntity<Map<String, String>> uploadImage(
        @RequestParam("file") MultipartFile file) {
    if (file.isEmpty()) {
        return ResponseEntity.badRequest().body(Collections.singletonMap("error", "文件为空"));
    }
    
    try {
        // 生成唯一文件名
        String originalFilename = file.getOriginalFilename();
        String fileExt = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = UUID.randomUUID().toString() + fileExt;
        String filePath = uploadDir + fileName;
        
        // 保存文件
        File dest = new File(filePath);
        file.transferTo(dest);
        
        // 返回图片访问路径(实际项目中可能是OSS地址)
        String imageUrl = "http://localhost:8080/api/image/" + fileName;
        return ResponseEntity.ok(Collections.singletonMap("url", imageUrl));
    } catch (IOException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Collections.singletonMap("error", "上传失败:" + e.getMessage()));
    }
}

@GetMapping("/{fileName}")
public ResponseEntity<Resource> getImage(@PathVariable String fileName) {
    File file = new File(uploadDir + fileName);
    Resource resource = new FileSystemResource(file);
    
    return ResponseEntity.ok()
            .contentType(MediaType.IMAGE_JPEG)  // 根据文件类型动态设置
            .body(resource);
}

}
二、Android 端图片选择与上传
使用系统相册选择图片,通过 Retrofit 上传到后端:
java
// 图片上传工具类
public class ImageUploader {
private static final int REQUEST_CODE_PICK_IMAGE = 100;
private Activity activity;
private ApiService apiService;

public ImageUploader(Activity activity) {
    this.activity = activity;
    this.apiService = RetrofitClient.getApiService();
}

// 打开相册选择图片
public void pickImage() {
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    activity.startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
}

// 处理图片上传
public void uploadImage(Uri imageUri, final OnUploadListener listener) {
    try {
        // 获取文件输入流
        InputStream inputStream = activity.getContentResolver().openInputStream(imageUri);
        if (inputStream == null) return;
        
        // 构建MultipartBody
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, bytesRead);
        }
        byte[] imageBytes = byteArrayOutputStream.toByteArray();
        
        RequestBody requestBody = RequestBody.create(
                MediaType.parse("image/jpeg"), imageBytes);
        MultipartBody.Part filePart = MultipartBody.Part.createFormData(
                "file", "image.jpg", requestBody);
        
        // 调用上传API
        apiService.uploadImage(filePart).enqueue(new Callback<ApiResponse<String>>() {
            @Override
            public void onResponse(Call<ApiResponse<String>> call, Response<ApiResponse<String>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    listener.onSuccess(response.body().getData());
                } else {
                    listener.onFailure("上传失败:" + (response.body() != null ? 
                            response.body().getMessage() : "未知错误"));
                }
            }
            
            @Override
            public void onFailure(Call<ApiResponse<String>> call, Throwable t) {
                listener.onFailure("网络错误:" + t.getMessage());
            }
        });
    } catch (IOException e) {
        listener.onFailure("文件读取失败:" + e.getMessage());
    }
}

// 回调接口
public interface OnUploadListener {
    void onSuccess(String imageUrl);
    void onFailure(String errorMsg);
}

}
三、集成云存储(以阿里云 OSS 为例)
添加 OSS 依赖:
xml

com.aliyun.oss
aliyun-sdk-oss
3.15.0

配置 OSS 参数:
properties
aliyun.oss.endpoint=oss-cn-hangzhou.aliyuncs.com
aliyun.oss.bucket-name=your-bucket-name
aliyun.oss.access-key-id=your-access-key
aliyun.oss.access-key-secret=your-access-secret

替换本地存储为 OSS 上传:
java
// OSS工具类
public class OSSClientUtil {
private OSS ossClient;
private String bucketName;

public OSSClientUtil(OSSProperties properties) {
    this.ossClient = new OSSClientBuilder().build(
            properties.getEndpoint(), 
            properties.getAccessKeyId(), 
            properties.getAccessKeySecret());
    this.bucketName = properties.getBucketName();
}

public String uploadFile(InputStream inputStream, String fileName) {
    ossClient.putObject(bucketName, fileName, inputStream);
    return "https://" + bucketName + "." + properties.getEndpoint() + "/" + fileName;
}

}

posted @ 2025-03-04 21:43  李蕊lr  阅读(21)  评论(0)    收藏  举报