1

I am trying to upload an image to a server using Angular as the front end and java ee web service jax rs rest easy as my back end. This my code for the angular/front end:

HTML page:

<md-card>
  <input type="file" (change)="onChange($event)" placeholder="Upload          files" >

</md-card>

For the component:

fileChange(event) {
    let fileList: FileList = event.target.files;
    let fileListLength = fileList.length;
    if(fileListLength > 0) {
        let formData:FormData = new FormData();
        for (var i = 0; i < fileListLength; i++) {
        formData.append("uploadFile[]", fileList[i]);
    }

    let headers = new Headers();
    headers.append('Content-Type', 'multipart/form-data');
    headers.append('Accept', 'application/json');
    let options = new RequestOptions({ headers: headers });
    this.http.post("http://localhost:8080/BCWEB/uploadProdImage", formData, options)
        .map(res => res.json())
        .catch(error => Observable.throw(error))
        .subscribe(
             data => console.log('success'),
             error => console.log(error)
        )
    }
}

For the backend java ee restful web service:

private static final String SERVER_UPLOAD_LOCATION_FOLDER = "C://Users/007EAA/Downloads/tes/";

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

    String fileName = "";

    Map<String, List<InputPart>> formParts = input.getFormDataMap();

    List<InputPart> inPart = formParts.get("file");

    for (InputPart inputPart : inPart) {

         try {

            // Retrieve headers, read the Content-Disposition header to obtain the original name of the file
            MultivaluedMap<String, String> headers = inputPart.getHeaders();
            fileName = parseFileName(headers);

            // Handle the body of that part with an InputStream
            InputStream istream = inputPart.getBody(InputStream.class,null);

            fileName = SERVER_UPLOAD_LOCATION_FOLDER + fileName;

            saveFile(istream,fileName);

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

        }

            String output = "File saved to server location : " + fileName;

    return Response.status(200).entity(output).build();
}

// Parse Content-Disposition header to get the original file name
private String parseFileName(MultivaluedMap<String, String> headers) {

    String[] contentDispositionHeader = headers.getFirst("Content-Disposition").split(";");

    for (String name : contentDispositionHeader) {

        if ((name.trim().startsWith("filename"))) {

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

            String fileName = tmp[1].trim().replaceAll("\"","");

            return fileName;
        }
    }
    return "randomName";
}

// save uploaded file to a defined location on the server
private void saveFile(InputStream uploadedInputStream,
    String serverLocation) {

    try {
        OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
        int read = 0;
        byte[] bytes = new byte[1024];

        outpuStream = new FileOutputStream(new File(serverLocation));
        while ((read = uploadedInputStream.read(bytes)) != -1) {
            outpuStream.write(bytes, 0, read);
        }
        outpuStream.flush();
        outpuStream.close();
    } catch (IOException e) {

        e.printStackTrace();
    }
}

The problem is No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had an HTTP status code of 500.

But when I try to add a user on the server, it gets added without any problem, so it's not a server problem. Can anyone help?

shim
  • 9,289
  • 12
  • 69
  • 108
  • thank you Syntactic Fructose but now am having another problem : "java.io.IOException: RESTEASY007550: Unable to get boundary for multipart" – abdel adim enn Apr 03 '17 at 14:02

1 Answers1

1

The issue is that your frontend and backend exist across different local hosts, and by default cross-origin requests are denied for security reasons.

You'll want to enable cross origin requests on your backend during testing, and disable it for production when your frontend and backend live in the same area. To enable cross origin, you'll need to add this provider snippet:

package com.yourdomain.package;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CORSFilter implements ContainerResponseFilter {

   @Override
   public void filter(final ContainerRequestContext requestContext,
                      final ContainerResponseContext cres) throws IOException {
      cres.getHeaders().add("Access-Control-Allow-Origin", "*");
      cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
      cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
      cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
      cres.getHeaders().add("Access-Control-Max-Age", "1209600");
   }

}

Info on CORS

Snippet pulled from this SO question

Community
  • 1
  • 1
Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177
  • thank you Syntactic Fructose but now am having another problem : "java.io.IOException: RESTEASY007550: Unable to get boundary for multipart" – abdel adim enn Apr 03 '17 at 02:02