Как загрузить файлы для загрузки в Amazon S3 Bucket с моим текущим кодом - PullRequest
0 голосов
/ 01 мая 2018

У меня есть это весеннее загрузочное приложение, которое использует традиционный способ загрузки и выгрузки документов (создавая папку на сервере), оно принимает файлы из html как составные, и у нас также есть наши веб-сервисы для приложений Android, которые отправляют данные на остальные контроллеры. затем base64 преобразует его в байтовый формат. Скажите, пожалуйста, как я могу реализовать тот же код для корзины s3 с минимальными изменениями.

Класс реализации сервиса

package com.erp.serviceimpl;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.erp.model.Document;
import com.erp.repository.DocumentRepository;
import com.erp.service.DocumentService;

@Service
public class DocumentServiceImpl implements DocumentService {

    @Autowired
    DocumentRepository documentrepository;

    // Save the uploaded file to this folder
    private static String UPLOADED_FOLDER = "s3://elasticbeanstalk-ap-south-1-461760552509/imagesUpload/";

    @Override
    public boolean uploadUserImage(MultipartFile file, Document document) {
        System.out.println("pooja" + file);
        boolean status = false;
        if (document != null) {
            document.setDate(new Date());
            document.setTurbine_id(document.getTurbine_id());
            Document documentImage = documentrepository.save(document);
            if (documentImage != null) {

                try {
                    byte[] bytes = file.getBytes();
                    Path path = Paths.get(UPLOADED_FOLDER + document.getDocId() + "_" + file.getOriginalFilename());
                    Files.write(path, bytes);

                } catch (IOException e) {
                    e.printStackTrace();
                }

                documentImage.setUploadImagesPath(document.getDocId() + "_" + file.getOriginalFilename());
                documentrepository.save(documentImage);
                return true;
            } else {
                return false;
            }
        }
        return status;
    }


    @Override
    public List<Document> getAllImages() {
        return documentrepository.findAll();
    }

    @Override
    public List<Document> findAllByTurbine_id(int turbine_id) {
        // TODO Auto-generated method stub
        Iterable<Document> itr = documentrepository.findAllByTurbine_id(turbine_id);
        return (List<Document>)itr;
    }

    @Override
    public boolean uploadUserWebServiceImage(Document document) {
        boolean status = false;
        if (document != null) {
            document.setDate(new Date());
            document.setTurbine_id(document.getTurbine_id());
            Document documentImage = documentrepository.save(document);
            if (documentImage != null) {
                try {
                    String[] img = document.getImageBase().split(",");
                    byte[] imageByte = Base64.decodeBase64(img[1]);
                    Path path = Paths.get(UPLOADED_FOLDER + documentImage.getDocId() + "_" + document.getUploadImagesPath());
                    Files.write(path, imageByte);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                documentImage.setUploadImagesPath(documentImage.getDocId() + "_" + document.getUploadImagesPath());
                documentrepository.save(documentImage);
                status = true;
                return status;
            }
        }
        return status;
    }

}

Класс контроллера.

package com.erp.controller;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.erp.model.Document;
import com.erp.service.DocumentService;
import com.erp.service.EmployeeService;
import com.erp.service.TurbineService;
import com.erp.utils.IConstant;

@Controller
@ComponentScan
public class DocumentController {

    @Autowired
    DocumentService documentService;

    @Autowired
    TurbineService turbineService;

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/addDocument/{turbine_id}")
    public String newDocument(@PathVariable Integer turbine_id, Model model) {
        Document document = new Document();
        document.setTurbine_id(turbine_id);
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        model.addAttribute("employee", employeeService.findEmployeeByUsername(auth.getName()));
        model.addAttribute("turbine", turbineService.findTurbine(turbine_id));
        model.addAttribute("addDocument", document);
        model.addAttribute("viewDocuments", (ArrayList<Document>) documentService.findAllByTurbine_id(turbine_id));
        return "turbine-documents";
    }

    @RequestMapping(value = "/documentUpload", method = { RequestMethod.GET, RequestMethod.POST })
    private String saveUploadImages(@RequestParam("file") MultipartFile file,
            @ModelAttribute("Document") Document document, ModelMap model,
            final RedirectAttributes redirectAttributes) {
        boolean status = documentService.uploadUserImage(file, document);
        if (status) {
            model.addAttribute(IConstant.MESSAGE, IConstant.UPLOAD_IMAGE_SUCCESS_MESSAGE);
            redirectAttributes.addFlashAttribute("message", IConstant.UPLOAD_IMAGE_SUCCESS_MESSAGE);
            redirectAttributes.addFlashAttribute("alertClass", "alert-success");
        } else {
            model.addAttribute(IConstant.MESSAGE, IConstant.UPLOAD_IMAGE_FAILURE_MESSAGE);
            redirectAttributes.addFlashAttribute("message", IConstant.UPLOAD_IMAGE_FAILURE_MESSAGE);
            redirectAttributes.addFlashAttribute("alertClass", "alert-danger");
        }

        return "redirect:/addDocument/" + document.getTurbine_id();
    }

    @RequestMapping(value = "download", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<byte[]> downloadFile(@RequestParam("uploadImagesPath") String uploadImagesPath)
            throws IOException {
        String filename = "s3://elasticbeanstalk-ap-south-1-461760552509/imagesUpload/" + uploadImagesPath;
        @SuppressWarnings("resource")
        InputStream inputImage = new FileInputStream(filename);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[512];
        int l = inputImage.read(buffer);
        while (l >= 0) {
            outputStream.write(buffer, 0, l);
            l = inputImage.read(buffer);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "image/jpeg");
        headers.set("Content-Type", "application/pdf");
        headers.set("Content-Disposition", "attachment; filename=\"" + uploadImagesPath + "");
        return new ResponseEntity<byte[]>(outputStream.toByteArray(), headers, HttpStatus.OK);
    }

}

Страница из тимьяна:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
    xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Documents</title>
<meta
    content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
    name="viewport" />
<link rel="shortcut icon" href="images/ctmi_favicon.png"
    th:href="@{/images/ctmi_favicon.png}" />
<link rel="apple-touch-icon" href="images/ctmi_favicon-57x57.png"
    th:href="@{/images/ctmi_favicon-57x57.png}" />
<link rel="apple-touch-icon" sizes="72x72"
    href="images/ctmi_favicon-72x72.png"
    th:href="@{/images/ctmi_favicon-72x72.png}" />
<link rel="apple-touch-icon" sizes="114x114"
    href="images/ctmi_favicon-114x114.png"
    th:href="@{/images/ctmi_favicon-114x114.png}" />

<!-- css -->
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"
    th:href="@{/css/bootstrap.min.css}" />
<link rel="stylesheet" type="text/css" href="css/font-awesome.min.css"
    th:href="@{/css/font-awesome.min.css}" />
<link rel="stylesheet" type="text/css" href="css/jquery-ui.min.css"
    th:href="@{/css/jquery-ui.min.css}" />
<link rel="stylesheet" type="text/css" href="css/style.css"
    th:href="@{/css/style.css}" />
<link rel="stylesheet" type="text/css" href="css/responsive.css"
    th:href="@{/css/responsive.css}" />


<!--[if IE]>
        <script src="js/html5shiv.js" th:src="@{/js/html5shiv.js}" ></script>
    <![endif]-->

<!-- js -->
<!-- js -->
<script type="text/javascript" src="js/jquery.min.js"
    th:src="@{/js/jquery.min.js}"></script>
<script type="text/javascript" src="js/bootstrap.min.js"
    th:src="@{/js/bootstrap.min.js}"></script>
<script type="text/javascript" src="js/jquery-ui.min.js"
    th:src="@{/js/jquery-ui.min.js}"></script>
<script type="text/javascript" src="js/custom.js"
    th:src="@{/js/custom.js}"></script>
</head>

<body class="alBody">
    <!-- Preloader -->
    <div class="preLoader"></div>

    <!-- Header -->
    <header>
        <div class="container">
            <div class="hdrLogo">
                <img src="images/chola_turbo_logo.png"
                    th:src="@{/images/chola_turbo_logo.png}" alt="cholaturbo Logo"
                    class="logoDefault" />
            </div>
            <div class="hdrRight">
                <div class="hdrrInr">
                    <div class="hdrrLeft">
                        <ul>
                            <li class="logoutIcn">
                                <a href="#" th:href="@{/page/home}">
                                    <i class="fa fa-home fa-7x" aria-hidden="true"></i>
                                </a>

                            </li>
                            <li class="logoutIcn">
                                <a href="#" th:href="@{/employee/edit/{employee_id}(employee_id=${employee.employee_id})}" >
                                    <i class="fa fa-user fa-7x" aria-hidden="true"></i>
                                </a>

                            </li>

                            <li class="logoutIcn"><a href="/logout"><i
                                    class="fa fa-sign-out" aria-hidden="true"></i></a></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </header>

    <!-- Body Content Sec -->
    <section class="bodyCnt">
        <!-- Top Bread Sec -->
        <div class="topBread">
            <div class="container">
                <ol class="breadcrumb">
                    <li><a href="#"
                        th:href="@{/client/{client_id}(client_id=${turbine.client_id})}">BACK</a></li>
                    <li class="active">Documents</li>
                </ol>
                <div class="addProj"></div>
            </div>
        </div>

        <!-- Main body page -->
        <div class="mbSec">
            <div class="container">
                <div class="dbWrap clearfix">

                    <div class="col-md-3">
                        <div class="bsSgl">
                            <div class="bsInr">

                                <div class="dbsHead">
                                    <h4>Turbine Details</h4>
                                </div>

                                <ul class="side-menu">
                                    <li><a href="turbine-details-new.html"
                                        th:href="@{/turbine/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Turbine
                                            Details </a></li>
                                    <li><a href="turbine-engneer-assigned.html"
                                        th:href="@{/AddAssignTurbine/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Engneer
                                            Assigned</a></li>
                                    <li><a href="turbine-site-report.html"
                                        th:href="@{/addAddService/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Site
                                            Report</a></li>
                                    <li><a href="turbine-site-readings.html"
                                        th:href="@{/readingPage/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Site
                                            Reading</a></li>
                                    <li><a href="turbine-material.html"
                                        th:href="@{/material/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Materials And Spares</a></li>
                                    <li><a href="turbine-documents.html"
                                        th:href="@{/addDocument/{turbine_id}(turbine_id=${addDocument.turbine_id})}"
                                        class="active">Documents</a></li>
                                    <li><a href="turbine-drawings.html"
                                        th:href="@{/addDrawing/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Drawings</a></li>
                                    <li><a href="turbine-ta-da.html"
                                        th:href="@{/AddDailyAllowance/{turbine_id}(turbine_id=${addDocument.turbine_id})}">TA
                                            DA Bill</a></li>
                                    <li sec:authorize="hasAuthority('ADMIN')"><a
                                        href="turbine-man-days-expenses.html"
                                        th:href="@{/ManDays/{turbine_id}(turbine_id=${addDocument.turbine_id})}">
                                            Man Days Expenses</a></li>
                                    <li><a href="turbine-client-delay.html"
                                        th:href="@{/addClientDelay/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Client
                                            Delay</a></li>
                                    <li sec:authorize="hasAuthority('ADMIN')"><a
                                        href="turbine-client-requests.html"
                                        th:href="@{/AddClientResponse/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Client
                                            Requests</a></li>
                                    <li><a href="turbine-generate-report"
                                        th:href="@{/generateReportPage/{turbine_id}(turbine_id=${addDocument.turbine_id})}">Generate
                                            Report</a></li>
                                </ul>
                            </div>

                        </div>

                    </div>
                    <!-- end left bar -->

                    <div class="col-md-9 bsSgl">
                        <div class="bsInr">
                            <div class="dbsHead">
                                <h4>Documents</h4>
                            </div>
                            <div th:if="${message}" th:text="${message}"
                                th:class="${'alert ' + alertClass}"></div>
                            <form class="row" action="#" th:action="@{/documentUpload}"
                                th:object="${addDocument}" method="post"
                                enctype="multipart/form-data">
                                <div class="bsMtr">
                                    <div class="col-md-9">
                                        <div class="snglInpt">
                                            <input type="file" name="file"
                                                placeholder="Upload Image" th:required="required" /> <input
                                                type="hidden" th:field="*{turbine_id}" name="turbine_id"
                                                id="turbine_id" placeholder="Turbine Id" />
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <button class="btn btn-success" type="submit">Submit</button>
                                    </div>
                                </div>
                            </form>
                        </div>

                        <div class="clearfix"></div>

                        <div class="bsInr mrg-top-20">
                            <div class="bsMtr">
                                <div class="table-responsive">
                                    <table class="table" id="doc_list">
                                        <tbody>
                                            <tr>

                                                <td>TurbineId</td>
                                                <td>Image</td>
                                                <td>Date</td>
                                                <td>Download Image</td>
                                            </tr>
                                            <tr th:each="viewDocument : ${viewDocuments}">
                                                <td th:text="${viewDocument.docId}"></td>
                                                <td th:text="${viewDocument.uploadImagesPath}"></td>
                                                <td th:text="${viewDocument.date}"></td>
                                                <td><a
                                                    th:href="@{|/download?uploadImagesPath=${viewDocument.uploadImagesPath}|}"><span
                                                        th:text="${viewDocument.uploadImagesPath}"></span></a></td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>


                    </div>
                    <!-- end col md 12 -->

                </div>

            </div>
        </div>
    </section>

    <!-- Footer -->
    <footer>
        <div class="container">
            <p>Copyright © 2018 cholaturbo</p>
        </div>
    </footer>


</body>
</html>

Контроллер отдыха для Android:

package com.erp.webService;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.erp.model.Document;
import com.erp.service.DocumentService;
import com.erp.utils.IConstant;

@RestController
@RequestMapping("/api")
public class DocumentWebService {

    @Autowired
    DocumentService documentService;

    private static String UPLOADED_FOLDER = "//var//sentora//hostdata//cholaerp//public_html//imagesUpload//";

    @RequestMapping(value = "uploadFile", method = RequestMethod.POST)
    public @ResponseBody Map<String, Object> saveUserImage(@RequestBody Document document) throws IOException {
        int turbine_id = document.getTurbine_id();
        Map<String, Object> map = new HashMap<String, Object>();
        boolean documents = documentService.uploadUserWebServiceImage(document);
        if (documents) {
            List<Document> list = documentService.findAllByTurbine_id(turbine_id);
            for (Document doc : list) {
                doc.setImageBase(null);
                doc.setUploadImagesPath(doc.getUploadImagesPath());
            }
            map.put(IConstant.RESPONSE, IConstant.RESPONSE_SUCCESS_MESSAGE);
            map.put(IConstant.MESSAGE, IConstant.UPLOAD_IMAGE_SUCCESS_MESSAGE);
            map.put(IConstant.DATA, list);
        } else {
            map.put(IConstant.RESPONSE, IConstant.RESPONSE_NO_DATA_MESSAGE);
            map.put(IConstant.MESSAGE, IConstant.UPLOAD_IMAGE_FAILURE_MESSAGE);
        }
        return map;
    }

    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<byte[]> downloadFile(@RequestParam("uploadImagesPath") String uploadImagesPath)
            throws IOException {
        String filename = "https://s3.console.aws.amazon.com//s3//buckets//elasticbeanstalk-ap-south-1-461760552509//?region=ap-south-1&tab=overview//imagesUpload//" + uploadImagesPath;
        @SuppressWarnings("resource")
        InputStream inputImage = new FileInputStream(filename);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[512];
        int l = inputImage.read(buffer);
        while (l >= 0) {
            outputStream.write(buffer, 0, l);
            l = inputImage.read(buffer);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "image/jpeg");
        headers.set("Content-Type", "application/pdf");
        headers.set("Content-Disposition", "attachment; filename=\"" + uploadImagesPath + "");
        return new ResponseEntity<byte[]>(outputStream.toByteArray(), headers, HttpStatus.OK);
    }

    @GetMapping(value = "/getAllImages", produces = "application/json")
    public List<Document> getAllImages() {
        return (List<Document>) documentService.getAllImages();
    }

    @GetMapping(value = "/getAllDocument/{turbine_id}", produces = "application/json")
    public List<Document> getAllByTurbineId(@PathVariable(value = "turbine_id") int turbine_id)  {
        return (List<Document>) documentService.findAllByTurbine_id(turbine_id);
    }
}

1 Ответ

0 голосов
/ 04 мая 2018

Почему бы вам не попробовать Spring Content ? Он делает именно то, что вам нужно, и вам не нужно писать любой этого кода.

Предполагается, что Maven, Spring Boot и Spring Data (дайте мне знать, если вы используете что-то еще): -

pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- HSQL -->
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.hateoas</groupId>
        <artifactId>spring-hateoas</artifactId>
    </dependency>
    <dependency>
        <groupId>com.github.paulcwarren</groupId>
        <artifactId>content-s3-spring-boot-starter</artifactId>
        <version>${spring-content-version}</version>
    </dependency>
    <dependency>
        <groupId>com.github.paulcwarren</groupId>
        <artifactId>content-rest-spring-boot-starter</artifactId>
        <version>${spring-content-version}</version>
    </dependency>
    ... 
<dependencies>

Обновите вашу сущность с помощью управляемых аннотаций Spring Content.

Document.java

@Entity    
public class Document {
  ...existing fields...

  @ContentId
  private String contentId;

  @ContentLength
  private Long contentLen;

  @MimeType
  private String mimeType;

  ...getters and setters...
}

Создайте соединение с вашим магазином S3. Хранилище S3 было реализовано для использования SimpleStorageResourceLoader, поэтому этот компонент будет в конечном итоге использоваться вашим магазином.

StoreConfig.java

  @Configuration
  @EnableS3Stores
  public class S3Config {

    @Autowired
    private Environment env;

    public Region region() {
        return Region.getRegion(Regions.fromName(System.getenv("AWS_REGION")));
    }

    @Bean
    public BasicAWSCredentials basicAWSCredentials() {
        return new BasicAWSCredentials(env.getProperty("AWS_ACCESS_KEY_ID"), env.getProperty("AWS_SECRET_KEY"));
    }

    @Bean
    public AmazonS3 client(AWSCredentials awsCredentials) {
        AmazonS3Client amazonS3Client = new AmazonS3Client(awsCredentials);
        amazonS3Client.setRegion(region());
        return amazonS3Client;
    }

    @Bean
    public SimpleStorageResourceLoader simpleStorageResourceLoader(AmazonS3 client) {
        return new SimpleStorageResourceLoader(client);
    }
  }

Определите Магазин, типизированный для Документа - поскольку это то, с чем вы связываете контент.

DocumentContentStore.java

@StoreRestResource(path="documentContent")
public interface DocumentStore extends ContentStore<Document, String> {
}

Когда вы запускаете это, вам также нужно установить ведро для вашего магазина. Это можно сделать, указав spring.content.s3.bucket в application.properties/yaml или установив переменную окружения AWS_BUCKET.

Этого достаточно для создания службы контента на основе REST для хранения контента на S3 и связывания этого контента с вашей сущностью Document. Spring Content увидит интерфейс Store и зависимости S3. Предположим, вы хотите хранить контент в S3 и внедрить реализацию вашего интерфейса для вас. Это означает, что вам не нужно реализовывать это самостоятельно. Вы сможете хранить контент, отправив запрос multipart-form-data на:

POST /documentcontent/{documentId}

и получить его снова с помощью:

GET /documentscontent/{documentId}

(служба поддерживает полное CRUD BTW и потоковое видео в случае, если это может быть важно).

Вы увидите, что Spring Content связывает контент с вашей сущностью, управляя аннотациями, связанными с контентом.

Может использоваться с или без Spring Data REST. Зависимости немного отличаются в зависимости. Я предположил, что вы не используете Spring Data REST. Дайте мне знать, если это не так, и я обновлю пример.

Здесь есть видео этого - демонстрация начинается примерно на полпути. Он использует модуль файловой системы не S3, но они взаимозаменяемы. Просто нужно выбрать правильные зависимости для типа магазина, который вы используете. S3 в вашем случае.

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...