Server and database file handling (post, get, delete) is working only partially in my spring boot project

huangapple go评论68阅读模式
英文:

Server and database file handling (post, get, delete) is working only partially in my spring boot project

问题

以下是您要翻译的内容:

"Only POST is working. GET and DELETE are throwing the following error when testing through Postman:

{
"timestamp": "2023-04-06T14:01:59.898+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/secure/test/file/bull.png"
}

I haven't worked with Multipart files before and I have a feeling that it's something regarding that that goes wrong, but I can't quite put my finger on what exactly. I'll put the relevant pieces of code in the following code blocks."

package server.api;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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 server.services.StorageService;

import java.io.IOException;

@SpringBootApplication
@RestController
@RequestMapping(value = {"/secure/{username}/{password}/file", "/secure/{username}/file"})
public class FileController {
    @Autowired
    private StorageService service;
    @PostMapping("/add")
    public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        String uploadFile = service.uploadFile(file);
        return ResponseEntity.status(HttpStatus.OK)
                .body(uploadFile);
    }
    @GetMapping("/{fileName}")
    public ResponseEntity<?> outputFile(@PathVariable String fileName){
        byte[] fileData=service.outputFile(fileName);
        return ResponseEntity.status(HttpStatus.OK)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(fileData);
    }
    @DeleteMapping("/{fileName}")
    public ResponseEntity<?> deleteFile(@PathVariable String fileName) {
        String message = service.deleteFile(fileName);
        return ResponseEntity.status(HttpStatus.OK)
                .body(message);
    }
}
package server.services;

import commons.FileData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import server.database.StorageRepository;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.utilOptional;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

@Service
public class StorageService {
    @Autowired
    private StorageRepository repository;

    public String uploadFile(MultipartFile file) throws IOException {
        repository.save(new FileData(file.getOriginalFilename(),
                file.getContentType(), compressFile(file.getBytes())));
        return "File uploaded succesfully: "+ file.getOriginalFilename();
    }
    public byte[] outputFile(String fileName){
        Optional<FileData> dbFileData = repository.findByName(fileName);
        byte[] file=decompressFile(dbFileData.get().getFileData());
        return file;
    }
    public String deleteFile(String fileName) {
        Optional<FileData> dbFileData = repository.findByName(fileName);
        if (dbFileData.isPresent()) {
            repository.delete(dbFileData.get());
            return "File deleted successfully: " + fileName;
        } else {
            return "File not found: " + fileName;
        }
    }
    public String getType(String fileName){
        Optional<FileData> dbFileData = repository.findByName(fileName;
        if (dbFileData.isPresent()) {
            return dbFileData.get().getType();
        } else {
            return "File not found: " + fileName;
        }
    }
    public static byte[] compressFile(byte[] data) {
        Deflater deflater = new Deflater();
        deflater.setLevel(Deflater.BEST_COMPRESSION);
        deflater.setInput(data);
        deflater.finish();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
        byte[] tmp = new byte(4*1024);
        while (!deflater.finished()) {
            int size = deflater.deflate(tmp);
            outputStream.write(tmp, 0, size);
        }
        try {
            outputStream.close();
        } catch (Exception ignored) {
        }
        return outputStream.toByteArray();
    }
    public static byte[] decompressFile(byte[] data) {
        Inflater inflater = new Inflater();
        inflater.setInput(data);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
        byte[] tmp = new byte(4*1024);
        try {
            while (!inflater.finished()) {
                int count = inflater.inflate(tmp);
                outputStream.write(tmp, 0, count);
            }
            outputStream.close();
        } catch (Exception ignored) {
        }
        return outputStream.toByteArray();
    }
}
package commons;

import lombok.Data;

import javax.persistence.*;

@Entity
@Table(name="FileData")
@Data
public class FileData {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String type;
    @Lob
    @Column(name="filedata")
    private byte[] fileData;
    public FileData(String name, String type, byte[] fileData) {
        this.name = name;
        this type = type;
        this.fileData = fileData;
    }
    public byte[] getFileData() {
        return fileData;
    }

    public String getType() {
        return type;
    }
    public String getName() {
        return name;
    }

    public Long getId() {
        return id;
    }
}
英文:

Only POST is working. GET and DELETE are throwing the following error when testing through Postman:

{
    "timestamp": "2023-04-06T14:01:59.898+00:00",
    "status": 500,
    "error": "Internal Server Error",
    "path": "/secure/test/file/bull.png"
}

I haven't worked with Multipart files before and I have a feeling that it's something regarding that that goes wrong, but I can't quite put my finger on what exactly. I'll put the relevant pieces of code in the following code blocks.

package server.api;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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 server.services.StorageService;

import java.io.IOException;

@SpringBootApplication
@RestController
@RequestMapping(value = {"/secure/{username}/{password}/file", "/secure/{username}/file"})
public class FileController {
    @Autowired
    private StorageService service;
    @PostMapping("/add")
    public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        String uploadFile = service.uploadFile(file);
        return ResponseEntity.status(HttpStatus.OK)
                .body(uploadFile);
    }
    @GetMapping("/{fileName}")
    public ResponseEntity<?> outputFile(@PathVariable String fileName){
        byte[] fileData=service.outputFile(fileName);
        return ResponseEntity.status(HttpStatus.OK)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(fileData);
    }
    @DeleteMapping("/{fileName}")
    public ResponseEntity<?> deleteFile(@PathVariable String fileName) {
        String message = service.deleteFile(fileName);
        return ResponseEntity.status(HttpStatus.OK)
                .body(message);
    }
}
package server.services;

import commons.FileData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import server.database.StorageRepository;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Optional;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

@Service
public class StorageService {
    @Autowired
    private StorageRepository repository;

    public String uploadFile(MultipartFile file) throws IOException {
        repository.save(new FileData(file.getOriginalFilename(),
                file.getContentType(), compressFile(file.getBytes())));
        return "File uploaded succesfully: "+ file.getOriginalFilename();
    }
    public byte[] outputFile(String fileName){
        Optional<FileData> dbFileData = repository.findByName(fileName);
        byte[] file=decompressFile(dbFileData.get().getFileData());
        return file;
    }
    public String deleteFile(String fileName) {
        Optional<FileData> dbFileData = repository.findByName(fileName);
        if (dbFileData.isPresent()) {
            repository.delete(dbFileData.get());
            return "File deleted successfully: " + fileName;
        } else {
            return "File not found: " + fileName;
        }
    }
    public String getType(String fileName){
        Optional<FileData> dbFileData = repository.findByName(fileName);
        if (dbFileData.isPresent()) {
            return dbFileData.get().getType();
        } else {
            return "File not found: " + fileName;
        }
    }
    public static byte[] compressFile(byte[] data) {
        Deflater deflater = new Deflater();
        deflater.setLevel(Deflater.BEST_COMPRESSION);
        deflater.setInput(data);
        deflater.finish();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
        byte[] tmp = new byte[4*1024];
        while (!deflater.finished()) {
            int size = deflater.deflate(tmp);
            outputStream.write(tmp, 0, size);
        }
        try {
            outputStream.close();
        } catch (Exception ignored) {
        }
        return outputStream.toByteArray();
    }
    public static byte[] decompressFile(byte[] data) {
        Inflater inflater = new Inflater();
        inflater.setInput(data);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
        byte[] tmp = new byte[4*1024];
        try {
            while (!inflater.finished()) {
                int count = inflater.inflate(tmp);
                outputStream.write(tmp, 0, count);
            }
            outputStream.close();
        } catch (Exception ignored) {
        }
        return outputStream.toByteArray();
    }
}
package commons;

import lombok.Data;

import javax.persistence.*;

@Entity
@Table(name="FileData")
@Data
public class FileData {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String type;
    @Lob
    @Column(name="filedata")
    private byte[] fileData;
    public FileData(String name, String type, byte[] fileData) {
        this.name = name;
        this.type = type;
        this.fileData = fileData;
    }
    public byte[] getFileData() {
        return fileData;
    }

    public String getType() {
        return type;
    }
    public String getName() {
        return name;
    }

    public Long getId() {
        return id;
    }
}

答案1

得分: 0

问题是FileData类缺少默认构造函数。

尽管我有一个带参数的构造函数,但这不被视为默认构造函数,因为默认构造函数必须没有参数。将这行代码添加到FileData类中解决了这个问题

public FileData() {}
英文:

The problem was the missing default constructor of the FileData class.

Even though I had one with parameters, that's not considered default as the default constructor has to be without parameters. Adding this line to the FileData class solved the issue

public FileData() {}

huangapple
  • 本文由 发表于 2023年4月6日 22:12:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75950531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定