3

Я пытаюсь загрузить файл в Google Cloud Storage. Мой Servlet кодЗагрузить файл в Google Cloud Storage через appengine

public class UploadFile extends HttpServlet { 

    private final String BUCKET = "XXXXXXXXX"; 
     private boolean isMultipart; 
     private String filePath; 
     private int maxFileSize = 5 * 1024 * 1024; 
     private int maxMemSize = 5 * 1024 * 1024; 
     private File file ; 

     public void init(){ 
      // Get the file location where it would be stored. 
      filePath = 
       getServletContext().getInitParameter("file-upload"); 
     } 
     public void doPost(HttpServletRequest request, 
        HttpServletResponse response) 
        throws ServletException, java.io.IOException { 
      // Check that we have a file upload request 
      isMultipart = ServletFileUpload.isMultipartContent(request); 
      response.setContentType("text/html"); 
      java.io.PrintWriter out = response.getWriter(); 
      if(!isMultipart){ 
      out.println("<html>"); 
      out.println("<head>"); 
      out.println("<title>Servlet upload</title>"); 
      out.println("</head>"); 
      out.println("<body>"); 
      out.println("<p>No file uploaded</p>"); 
      out.println("</body>"); 
      out.println("</html>"); 
      return; 
      } 
      DiskFileItemFactory factory = new DiskFileItemFactory(); 
      // maximum size that will be stored in memory 
      factory.setSizeThreshold(maxMemSize); 
      // Location to save data that is larger than maxMemSize. 
      factory.setRepository(new File("/temp/image/")); 

      // Create a new file upload handler 
      ServletFileUpload upload = new ServletFileUpload(factory); 
      // maximum file size to be uploaded. 
      upload.setSizeMax(maxFileSize); 

      try{ 
      // Parse the request to get file items. 
      List fileItems = upload.parseRequest(request); 

      // Process the uploaded file items 
      Iterator i = fileItems.iterator(); 

      out.println("<html>"); 
      out.println("<head>"); 
      out.println("<title>Servlet upload</title>"); 
      out.println("</head>"); 
      out.println("<body>"); 
      while (i.hasNext()) 
      { 
      FileItem fi = (FileItem)i.next(); 
      if (!fi.isFormField()) 
      { 
       // Get the uploaded file parameters 
       String fieldName = fi.getFieldName(); 
       String fileName = fi.getName(); 
       String contentType = fi.getContentType(); 
       boolean isInMemory = fi.isInMemory(); 
       long sizeInBytes = fi.getSize(); 
       // Write the file 
       if(fileName.lastIndexOf("\\") >= 0){ 
        file = new File(filePath + 
        fileName.substring(fileName.lastIndexOf("\\"))) ; 
       }else{ 
        file = new File(filePath + 
        fileName.substring(fileName.lastIndexOf("\\")+1)) ; 
       } 

       String path = Events.uploadFile (fileName, "image/*", file, BUCKET); 

       // fi.write(file) ; 
       out.println("Uploaded Filename: " + fileName + "<br>"+ " File Path:"+ path); 
      } 
      } 
      out.println("</body>"); 
      out.println("</html>"); 
     }catch(Exception ex) { 
      System.out.println(ex); 
     } 
     } 
     public void doGet(HttpServletRequest request, 
          HttpServletResponse response) 
      throws ServletException, java.io.IOException { 

      throw new ServletException("GET method used with " + 
        getClass().getName()+": POST method required."); 
     } 
    } 

web.xml функция

<servlet> 
     <servlet-name>UploadFile</servlet-name> 
     <servlet-class>XXXXXXXXXX.UploadFile</servlet-class> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>UploadFile</servlet-name> 
     <url-pattern>/uploadManager/UploadFile</url-pattern> //Based on your original URL 
    </servlet-mapping> 

FileUpload, чтобы сохранить файл в ГКС

public static String uploadFile (String name, String contentType, File file, String bucketName) 
      throws IOException, GeneralSecurityException 
    { 

     InputStreamContent contentStream = new InputStreamContent (contentType, new FileInputStream (file)); 

     // Setting the length improves upload performance 
     contentStream.setLength (file.length()); 

     StorageObject objectMetadata = new StorageObject() 
       // Set the destination object name 
       .setName (name) 
       // Set the access control list to publicly read-only 
       .setAcl (Arrays.asList (new ObjectAccessControl().setEntity ("allUsers").setRole ("READER"))); 

     // Do the insert 
     Storage client = StorageFactory.getService(); 
     Storage.Objects.Insert insertRequest = client.objects().insert (bucketName, objectMetadata, contentStream); 

     insertRequest.execute(); 
     return "https://storage.cloud.google.com/" + BUCKET + "/" + file.getName(); 
    } 

Но когда я пытаюсь проверить это с некоторыми тестирования API клиента он дает ошибку

org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found 

Furt ее после того, как интегрировать его с UI, который находится в угловых и тестирование его на месте, я столкнулся этот вопрос

Cross-Origin Request Blocked Reason: CORS header 'Access-Control-Allow-Origin' missing 

Я попытался решить эту проблему, но не нашли никакого решения, соответствующего Google AppEngine.


Изначально я пытаюсь загрузить файл через этот код, но в ближайшем будущем тот же код будет использоваться для загрузки в формате .pdf и .html файлов в ГКС.

Для справки: Я использую конечные точки Google для других моих потребностей в передаче данных с клиентским концом. Клиент End - это сборка webapp в Angular, но она будет распространена на android и ios.

Любая помощь будет оценена по достоинству.

Спасибо

UPDATE 1/8/2016

Теперь я получаю файл на сервере, но я не знаю, где я должен временно сохранить файл перед его отправкой в ​​Google Cloud Storage , При хранении файла в

war\WEB-INI\ 

и исключение я облицовка

java.security.AccessControlException: access denied ("java.io.FilePermission" "\war\WEB-INI\profile.png" "read") 

ответ

4

Наконец-то я могу загрузить файл с клиентской части в Google Cloud Storage с помощью appengine.

Я полагаю, что перед выполнением этих шагов вы следующие вещи готовы

  • JSON файл из вашей учетной записи службы.
  • Создан ковш по умолчанию.

Шаг 1: Сделайте Servlet, как это

package XXXXXXXXX; 

import java.io.IOException; 
import java.io.InputStream; 
import java.security.GeneralSecurityException; 
import java.util.Arrays; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import com.google.api.client.http.InputStreamContent; 
import com.google.api.services.storage.Storage; 
import com.google.api.services.storage.model.ObjectAccessControl; 
import com.google.api.services.storage.model.StorageObject; 

import XXXXXXXXXXXXX.StorageFactory; 

//@author Umesh Chauhan 

/** 
* Save File to GCS 
* 
* @param fileName  File Name with format 
* @header Content-Type "*/*" 
* @return file path 
* @throws Exception  Any Error during upload 
*/ 
public class UploadFile extends HttpServlet 
{ 

    private static final long serialVersionUID = 1L; 
    private final String BUCKET = "YOUR BUCKET NAME"; 
    private int maxFileSize = 6 * 1024 * 1024; 

    @Override 
    protected void doOptions (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
    { 
     // pre-flight request processing 
     resp.setHeader ("Access-Control-Allow-Origin", "*"); 
     resp.setHeader ("Access-Control-Allow-Methods", "*"); 
     resp.setHeader ("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
    } 

    @Override 
    public void doPost (HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, java.io.IOException 
    { 

     try 
     { 
      String path = uploadFile (request.getParameter ("fileName"), request.getContentType(), 
        request.getInputStream(), BUCKET, request.getInputStream().available()); 
      // Sending Response 
      response.setStatus (HttpServletResponse.SC_OK); 
      response.getWriter().write (path); 
      response.getWriter().flush(); 
      response.getWriter().close(); 

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

    public String uploadFile (String name, String contentType, InputStream input, String bucketName, 
      int contentLength) throws IOException, GeneralSecurityException 
    { 

     InputStreamContent contentStream = new InputStreamContent (contentType, input); 

     if (contentLength < maxFileSize) 
     { 

      // It is done Automatically. 
      /* 
      * // Setting the length improves upload performance 
      * contentStream.setLength (contentLength); 
      */ 

      StorageObject objectMetadata = new StorageObject() 
        // Set the destination object name 
        .setName (name) 
        // Set the access control list to publicly read-only 
        .setAcl (Arrays.asList (
          new ObjectAccessControl().setEntity ("allUsers").setRole ("READER"))); 

      // Do the insert 
      Storage client = StorageFactory.getService(); 

      Storage.Objects.Insert insertRequest = client.objects() 
        .insert (bucketName, objectMetadata, contentStream); 

      insertRequest.execute(); 

      return "https://storage.cloud.google.com/" + BUCKET + "/" + name; 
     } 
     else 
     { 
      throw new GeneralSecurityException ("File size canot be more then 6 MB !"); 
     } 
    } 

    public void doGet (HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, java.io.IOException 
    { 
     throw new ServletException ("GET method used with " + getClass().getName() + ": POST method required."); 
    } 

} 

Шаг 2: Ваша фабрика хранения

package XXXXXXXXXXXX; 

import java.io.IOException; 
import java.net.URL; 
import java.security.GeneralSecurityException; 
import java.util.Collection; 

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; 
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; 
import com.google.api.client.http.HttpTransport; 
import com.google.api.client.json.JsonFactory; 
import com.google.api.client.json.jackson2.JacksonFactory; 
import com.google.api.services.storage.Storage; 
import com.google.api.services.storage.StorageScopes; 

//@author Umesh Chauhan 

public class StorageFactory 
{ 

    private static Storage instance = null; 

    public static synchronized Storage getService() throws IOException, GeneralSecurityException 
    { 
     if (instance == null) 
     { 
      instance = buildService(); 
     } 
     return instance; 
    } 

    private static Storage buildService() throws IOException, GeneralSecurityException 
    { 

     HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport(); 
     JsonFactory jsonFactory = new JacksonFactory(); 

     GoogleCredential credential = GoogleCredential.fromStream (
       new URL ("HERE GOES THE URL FOR YOUR SERVICE ACCOUNT JSON - I USED GOOGLE DRIVE DIRECT DOWNLOAD LINK TO MY JSON FILE") 
         .openStream()); 

     // Depending on the environment that provides the default credentials 
     // (for 
     // example: Compute Engine, App Engine), the credentials may require us 
     // to 
     // specify the scopes we need explicitly. Check for this case, and 
     // inject 
     // the Cloud Storage scope if required. 
     if (credential.createScopedRequired()) 
     { 
      Collection<String> scopes = StorageScopes.all(); 
      credential = credential.createScoped (scopes); 
     } 

     return new Storage.Builder (transport, jsonFactory, credential).setApplicationName ("YOUR PROJECT NAME").build(); 
    } 
} 

Шаг 3: Обновление вам web.xml

<servlet> 
     <servlet-name>UploadFile</servlet-name> 
     <servlet-class>PACKAGE.UploadFile</servlet-class> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>UploadFile</servlet-name> 
     <url-pattern>/uploadManager/UploadFile</url-pattern> //Based on your original URL 
    </servlet-mapping> 
+0

«ЗДЕСЬ ИДЕТ НА URL ДЛЯ ОБСЛУЖИВАНИЯ СЧЕТА JSON - Я ИСПОЛЬЗУЕТСЯ GOOGLE ПРИВОД Прямая ссылка К МОЕМУ JSON ФАЙЛ», как сгенерировать JSON учетной записи службы? можете ли вы привести пример структуры? – dina

+0

@ user5980143 необходимо загрузить его с консоли Google. –

+0

Если я уже запущен в google-приложении, мне не нужен «GoogleCreditial»? –

1

Прежде всего, необходимо решить проблему CORS в предварительной обработке запроса полета, что вам нужно сделать это на заднем конце: на Google App Engine это делается путем добавления doOptions метод как:

@Override 
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
{ 
    resp.setHeader("Access-Control-Allow-Origin", "*"); 
    resp.setHeader("Access-Control-Allow-Methods", "*"); 
    resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
} 

, то вам необходимо убедиться, что вы посылаете запрос с заголовком, как Content-Type: multipart/form-data, в противном случае ваш файл Wi будет неправильно закодировано. В angular2 заголовки запроса устанавливаются в качестве третьего (необязательного) параметра в запросе пост как:

let headers = new Headers(); 
headers.append('content-type', 'multipart/form-data'); 
http.post(url, body, { 
        headers:headers 
       }) 
1

Я сожалею, это не непосредственно на Ваш вопрос, но я хочу, чтобы указать на это в любом случае. Я рекомендую использовать одну из ваших обычных конечных точек для создания временного URL-адреса загрузки, который может использовать ваш угловой клиент, чтобы отправить файл непосредственно в облачное хранилище, не просматривая приложение. Один из способов сделать это - через API blobstore, как описано here. Вы можете загрузить в облачное хранилище через этот API, как описано here (далее на той же странице).

Это уменьшает объем кода загрузки, который вам нужен на вашем сервере, не подлежит ограничению 32 МБ для запросов GAE и соответствует рекомендациям Google (см. Ссылки на документацию выше).

2

Вот правильный путь для загрузки на хранение согласно docs

import com.google.appengine.tools.cloudstorage.*; 

public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { 
    String buffer = "the data to be saved in GCS bla bla"; 
    GcsFileOptions instance = GcsFileOptions.getDefaultInstance(); 
    GcsFilename fileName = new GcsFilename("bucketName", "fileName"); 
    GcsOutputChannel outputChannel; 
    gcsService.createOrReplace(fileName, instance, ByteBuffer.wrap(buffer.getBytes())); 
} 

вы найдете полный код here

+0

это 100% правильный способ сделать это, оригинальный вопрос сказал, что его приложение работает в «Google App Engine!» –

+0

Я разместил еще один вариант https://stackoverflow.com/questions/38590971/ upload-file-to-google-cloud-storage-via-appengine/47546249? s = 4 | 31.2540 # 47546249 библиотека 'com.google.cloud.storage' более поддерживается, чем' com.google.appengine' – dina

1

использование com.google.cloud.storage

  • , когда не работает на AppEngine - нет необходимости в проверке подлинности
  • при запуске локально запустить gcloud auth application-default login команду см authentication

    import com.google.cloud.storage.*; 
    
    
    public static void upload(String bucketName, String fileId, String content) throws IOException { 
        Storage storage = StorageOptions.newBuilder().build().getService(); 
    
        BlobInfo fileInfo = BlobInfo.newBuilder(bucketName, fileId) 
          .build(); 
    
        InputStream fileIS = IOUtils.toInputStream(content, "UTF-8"); 
        storage.create(fileInfo, fileIS); 
    
    } 
    
Смежные вопросы