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?

1
  • thank you Syntactic Fructose but now am having another problem : "java.io.IOException: RESTEASY007550: Unable to get boundary for multipart" Commented Apr 3, 2017 at 14:02

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

1 Comment

thank you Syntactic Fructose but now am having another problem : "java.io.IOException: RESTEASY007550: Unable to get boundary for multipart"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.