【问题标题】:Java InputStream object using getResourceAsStream is null when calling from web application but works when run in Eclipse使用 getResourceAsStream 的 Java InputStream 对象在从 Web 应用程序调用时为空,但在 Eclipse 中运行时有效
【发布时间】:2018-02-22 11:35:41
【问题描述】:

我的代码使用getResourceAsStream 方法创建InputStream 对象。

该文件与该类位于同一个包中,因此我引用的文件没有斜线或点。

当我在 Eclipse 中运行时,这可以正常工作,但是,当我从我的网络应用程序调用时,它始终为 null - 它找不到文件。

java.lang.NullPointerException
        at java.io.Reader.<init>(Reader.java:78)
        at java.io.InputStreamReader.<init>(InputStreamReader.java:72)
        at google.GoogleDrive.authorize(GoogleDrive.java:84)
        at google.GoogleDrive.getDriveService(GoogleDrive.java:106)
        at google.GoogleDrive.uploadFile(GoogleDrive.java:123)

这是完整的课程:

package google;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.FileContent;
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.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;

import play.Configuration;
import utils.AppGlobals.StringControl;

public class GoogleDrive {
    /** Application name. */
    private static final String APPLICATION_NAME = "Case Manager";

    /** Directory to store user credentials for this application. */
    private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),
            ".credentials/googledrivejava");

    /** Global instance of the {@link FileDataStoreFactory}. */
    private static FileDataStoreFactory DATA_STORE_FACTORY;

    /** Global instance of the JSON factory. */
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    /** Global instance of the HTTP transport. */
    private static HttpTransport HTTP_TRANSPORT;

    /** Credentials File Name **/
    private static String credentialsFileName = "client_secret.json";

    /**
     * Global instance of the scopes required by this quickstart.
     *
     * If modifying these scopes, delete your previously saved credentials at
     * ~/.credentials/drive-java-quickstart
     */
    // private static final List<String> SCOPES =
    // Arrays.asList(DriveScopes.DRIVE_METADATA_READONLY);
    private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);

    static {
        try {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
        } catch (Throwable t) {
            t.printStackTrace();
            System.exit(1);
        }
    }

    /**
     * Creates an authorized Credential object.
     * 
     * @return an authorized Credential object.
     * @throws IOException
     */
    public static Credential authorize() throws IOException {
        Credential credential = null;
        try {
            // Load client secrets...
            InputStream in = GoogleDrive.class.getResourceAsStream("client_secret.json");
            GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

            // Build flow and trigger user authorization request.
            GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
                    clientSecrets, SCOPES).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();
            credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
            System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
        } catch (IOException ex) {
            System.out.println(ex.toString());
            System.out.println("Could not find file " + credentialsFileName);
            ex.printStackTrace();
        }
        return credential;
    }

    /**
     * Build and return an authorized Drive client service.
     * 
     * @return an authorized Drive client service
     * @throws IOException
     */
    public static Drive getDriveService() throws IOException {
        Credential credential = authorize();
        return new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
    }

    public static void main(String[] args) throws IOException {
        try {
            uploadFile("C:\\WebDev\\license.txt");
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
        }
    }

    public static String uploadFile(String fullFilePath) throws IOException {
        String fileID = "";
        try {
            // Build a new authorized API client service.
            Drive service = getDriveService();

            File fileMetadata = new File();
            String fileName = StringControl.rightBack(fullFilePath, "\\");
            String fileContentType = getContentType(fileName);
            fileMetadata.setName(fileName);

            // Set the folder...
            String folderID = Configuration.root().getString("google.drive.folderid");
            fileMetadata.setParents(Collections.singletonList(folderID));

            java.io.File filePath = new java.io.File(fullFilePath);
            FileContent mediaContent = new FileContent(fileContentType, filePath);
            File file = service.files().create(fileMetadata, mediaContent).setFields("id, parents").execute();
            fileID = file.getId();
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
        }
        return fileID;
    }

    public static String getContentType(String filePath) throws Exception {
        String type = "";
        try {
            Path path = Paths.get(filePath);
            type = Files.probeContentType(path);
            System.out.println(type);
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
        }
        return type;
    }

}

我从这篇文章中尝试了几个不同的选项: Eclipse Java File FileInputStream vs Input Stream when loading font file

但没有运气。感谢您的帮助。

【问题讨论】:

  • 该文件是否在指定位置的 webapp 中可用?
  • 如果它是一个 webapp 它应该有一个资源文件夹。把json文件放在那里。
  • 该文件在您的 WAR 文件中的路径是什么?
  • 这是一个 Play Framework 应用程序 - 资源文件夹在哪里?
  • 我没有 WAR 文件。

标签: java eclipse inputstream


【解决方案1】:

检查在编译 Web 应用程序时资源是否包含在目标目录中。您的 json 文件可能没有与您编译的类一起复制,因此您将获得 null。

【讨论】:

  • 如果我将client_secret.json 文件放入另一个文件夹,例如app 文件夹,它是google 包上方的文件夹,我将如何引用它?或者放置此文件的最佳位置是什么?我将如何在 InputStream 对象中引用?
  • 我认为您可以解析文件的路径,将其与用户目录路径相结合,可以使用System.getProperty("user.dir") 读取。但同时,我认为在你的情况下,如果你愿意的话,可以使用与你的代码相同的包中的 json 文件。您只需要确保该文件在那里。如何实现,取决于您的环境。例如,如果您使用 Maven,则必须将 json 文件放在具有相同包路径的项目的资源文件夹中。
猜你喜欢
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多