0

I'm developing web application and need to make upload of files possible for users. The upload folder is outside of web application - in openstack data folder (set in standalone.xml) - example:

    <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <location name="/folder" handler="folder"/>
                    <filter-ref name="server-header"/>
                    <filter-ref name="x-powered-by-header"/>
                </host>
...

            <handlers>
                <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
                <file name="folder" path="/absolute/path/on/server" directory-listing="true"/>
            </handlers>

If I need to access the files, there is no problem (I just type mydomain.com/folder/xyz.jpg), but I need to reference the folder from the Java code (get the path of folder and then upload file in it by user). My Java REST interface serving the upload looks like this:

public class DictateUploadResource {

    public static final String UPLOADED_FILE_PARAMETER_NAME = "file";
    private final String UPLOAD_DIR = servletContext.getRealPath("/folder");


    @POST
    @Consumes("multipart/form-data")
    public Response uploadFile(MultipartFormDataInput input) {

        String path = servletContext.getRealPath("/folder");
        LOGGER.warn(">>>> sit back - starting file upload..." + path);

        Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
        List<InputPart> inputParts = uploadForm.get(UPLOADED_FILE_PARAMETER_NAME);

        for (InputPart inputPart : inputParts) {
            MultivaluedMap<String, String> headers = inputPart.getHeaders();
            String filename = getFileName(headers);


            try {
                InputStream inputStream = inputPart.getBody(InputStream.class, null);

                byte[] bytes = IOUtils.toByteArray(inputStream);

                LOGGER.info(">>> File '{}' has been read, size: #{} bytes", filename, bytes.length);
                writeFile(bytes, path + "/" + filename);
            } catch (IOException e) {
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
            }
        }
        return Response.status(Response.Status.OK).build();
    }

    /**
     * Build filename local to the server.
     *
     * @param filename
     * @return
     */
    private String getServerFilename(String path, String filename) {
        return path + "/" + filename;
    }

    private void writeFile(byte[] content, String filename) throws IOException {
        LOGGER.info(">>> writing #{} bytes to: {}", content.length, filename);
        File file = new File(filename);

        if (!file.exists()) {
            file.createNewFile();
        }

        FileOutputStream fop = new FileOutputStream(file);

        fop.write(content);
        fop.flush();
        fop.close();
        LOGGER.info(">>> writing complete: {}", filename);
    }

    /**
     * Extract filename from HTTP heaeders.
     *
     * @param headers
     * @return
     */
    private String getFileName(MultivaluedMap<String, String> headers) {
        String[] contentDisposition = headers.getFirst("Content-Disposition").split(";");

        for (String filename : contentDisposition) {
            if ((filename.trim().startsWith("filename"))) {

                String[] name = filename.split("=");

                String finalFileName = sanitizeFilename(name[1]);
                return finalFileName;
            }
        }
        return "unknown";
    }

    private String sanitizeFilename(String s) {
        return s.trim().replaceAll("\"", "");
    }

}

Thanks in advance!

konqi
  • 5,137
  • 3
  • 34
  • 52

2 Answers2

0

The easiest solution would be to use a system property as the path attribute allows expressions. Then in your code just retrieve the property.

Here's a CLI example:

/system-property=static.content.dir:add(value="/absolute/path/on/server")

Then to change the host:

/subsystem=undertow/configuration=handler/file=folder:write-attribute(name=path, value="${static.content.dir}")

You could always use a management client to and read the management resource to get the name if a system property is not acceptable. A system property is easiest though.

James R. Perkins
  • 16,800
  • 44
  • 60
  • everything's done, still does not work - writes "No such file or directory"... are you sure that you don't have to add some special rights to allow directory to be writable? – Jakub Rumanovsky Jan 02 '16 at 12:48
  • The user running the WildFly process would need read access to show files and write access to write files. That's on the OS side though. – James R. Perkins Jan 03 '16 at 23:20
0

STEP # 1 : create config file in src folder of web application

enter image description here

STEP # 2 : Here is my config file

enter image description here

STEP # 3 : Now i choose the event file and get the config properties relative to it and read the connectionURL from the properties file

enter image description here

  InputStream propertiesInputStream = null;
  Properties properties = new Properties();
  propertiesInputStream = EventService.class.getClassLoader().getResourceAsStream("/config.properties");
  properties.load(propertiesInputStream);
  String connUrl = properties.getProperty("connectionUrl");
Mohsin Ejaz
  • 316
  • 3
  • 7