Как передать MultipartFile / InputStream в доменную логи c чистым способом? - PullRequest
0 голосов
/ 13 марта 2020

Часть моего алгоритма использования, которая имеет отношение к вопросу, выглядит следующим образом:

  1. Проверьте, существует ли пользователь
  2. Проверьте, может ли пользователь получить файл
  3. Сохранить файл во временное хранилище

Моя реализация третьего пункта будет копировать InputStream содержимое в новый файл на диске. Это произошло бы в слое Server Application. Тем не менее, его необходимо вызывать из уровня домена, что требует прохождения InputStream через уровень домена.

Хотя я могу сохранить файл и передать только некоторую ссылку на него в лог домена c, я бы хотел этого избежать, потому что, если я прав, это приведет к ненужным операциям чтения и записи.

Ответы [ 2 ]

0 голосов
/ 14 марта 2020

Попробуйте: -

Объект, для которого я сохраняю или выбираю файл: -

@Data
public class OrganizationDTO implements IBaseDto {
    private Long id;
    @NotBlank(message = "Company name should not empty")
    private String companyName;
    private String headerLogo;
    private String footerSign;
}

Конфигурация контроллера: -

        @Autowired
    private OrganizationService service;

    @PostMapping(path = "/save", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
            public GenericDataDTO save(@RequestParam(required = true) String entityDTOString
                    , @RequestParam("file") MultipartFile[] headerLogo
            ) throws Exception {
                OrganizationDTO convDTO = new OrganizationDTO();
                GenericDataDTO genericDataDTO = new GenericDataDTO();
                genericDataDTO.setResponseMessage("Success");
                genericDataDTO.setResponseCode(HttpStatus.OK.value());
                try {
                    convDTO = new ObjectMapper().readValue(entityDTOString, OrganizationDTO.class);
                    if (null != headerLogo[0]) {
                        convDTO.setHeaderLogo(saveFileToServer(headerLogo[0]));
                    }
                    if (headerLogo.length >= 2 && null != headerLogo[1]) {
                        convDTO.setFooterSign(saveFileToServer(headerLogo[1]));
                    }
                    OrganizationDTO dtoData = service.saveEntity(convDTO);
                    genericDataDTO.setData(dtoData);
                    genericDataDTO.setTotalRecords(1);
                    return genericDataDTO;
                } catch (JsonProcessingException e) {
     genericDataDTO.setResponseCode(HttpStatus.FAILED_DEPENDENCY.value()); 
 genericDataDTO.setResponseMessage(HttpStatus.FAILED_DEPENDENCY.getReasonPhrase());
                    return genericDataDTO;
                } catch (IOException e) {
                    genericDataDTO.setResponseCode(HttpStatus.NOT_MODIFIED.value());
                    genericDataDTO.setResponseMessage("File not saved");
                    return genericDataDTO;
                }
            }

Мой GenericDataDTO - это Например: -

@Data
public class GenericDataDTO {
        private int responseCode;
        private String responseMessage;
        private Object data;
        private List dataList;
        private int totalRecords = 0;

        public static GenericDataDTO getGenericDataDTO(List entityList) {
            GenericDataDTO genericDataDTO = new GenericDataDTO();
            genericDataDTO.setDataList(entityList);
            genericDataDTO.setResponseCode(HttpStatus.OK.value());
            if (null == entityList) {
                genericDataDTO.setTotalRecords(0);
            } else {
                genericDataDTO.setTotalRecords(entityList.size());
            }
            genericDataDTO.setResponseMessage("Success");
            return genericDataDTO;
        }
    }

И глобальный метод, который хранит файл на сервере или временное хранилище: -

      public String saveFileToServer(MultipartFile argFile) throws IOException {
        String fileName = "Test";
        if (null != argFile) {
            fileName = (null != argFile.getOriginalFilename())
                    ? argFile.getOriginalFilename().replace("/", "_").trim()
                    : fileName;
        }
        File file = new File("Your_temp_storage_path" + LocalDateTime.now() + "_" + fileName);
        try {
            boolean isCreated = file.createNewFile();
            if (!isCreated) {
                throw new FileNotCreatedException();
            }
            if (null != argFile) {
                FileOutputStream fout = new FileOutputStream(file);
                fout.write(argFile.getBytes());
                fout.close();
            }
            return file.getName();
        } catch (IOException e) {
            throw new FileNotCreatedException();
        }
    }

И исключение выглядит так: -

public class FileNotCreatedException extends IOException {
    public FileNotCreatedException() {
        super("File not created");
    }

    public FileNotCreatedException(String msg) {
        super(msg);
    }
}

0 голосов
/ 13 марта 2020

Шаги 1 и 2 предназначены для аутентификации и авторизации, они должны быть в фильтре или даже лучше: настроены в вашем SecurityConfig. см. полезную ссылку, если вы не знакомы: https://www.baeldung.com/java-config-spring-security

Шаг 3 должен быть единственным, фактически вызванным на уровне вашего контроллера.

Редактировать : Если я правильно понимаю, вы действительно не хотите передавать ссылку на inputStream, если файл небольшой, вы можете проанализировать его как byte[] или resource и передать все это вашим службам, если файл большой, тогда вам, вероятно, придется создать временный файл и передать путь к файлу вашим службам:

...