Skip to content

Commit

Permalink
Merge pull request #948 from andymc12/418-multipart-support
Browse files Browse the repository at this point in the history
[418] multipart/form-data support
  • Loading branch information
andymc12 authored May 18, 2021
2 parents fce3aa5 + b5319b0 commit 48987b9
Show file tree
Hide file tree
Showing 9 changed files with 647 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*******************************************************************
* Copyright (c) 2021 Eclipse Foundation
*
* This specification document is made available under the terms
* of the Eclipse Foundation Specification License v1.0, which is
* available at https://www.eclipse.org/legal/efsl.php.
*******************************************************************/
package jaxrs.examples.multipart;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.EntityPart;
import jakarta.ws.rs.core.GenericType;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;


public class MultipartClient {
Logger LOG = Logger.getLogger(MultipartClient.class.getName());

public boolean sendPdfs(Path dir) throws IOException {
List<EntityPart> parts = Files.list(dir).map(this::toPart).collect(Collectors.toList());
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9080/multipart?dirName=abc");
Entity<List<EntityPart>> entity = Entity.entity(parts, MediaType.MULTIPART_FORM_DATA);
Response response = target.request().post(entity);
return response.getStatus() == 200;
}

private EntityPart toPart(Path file) {
String filename = file.getFileName().toString();
try {
return EntityPart.withName(filename)
.content(filename, Files.newInputStream(file))
.mediaType("application/pdf")
.build();
} catch (IOException ioex) {
LOG.log(Level.WARNING, "Failed to process file {0}", file);
return null;
}
}

public List<Path> retrievePdfs(String remoteDirName) throws IOException {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9080/multipart").queryParam("dirName", remoteDirName);
Response response = target.request(MediaType.MULTIPART_FORM_DATA).get();
List<EntityPart> parts = response.readEntity(new GenericType<List<EntityPart>>() {});
return parts.stream().map(part -> {
try (InputStream is = part.getContent()) {
Path file = Files.createFile(Paths.get(part.getFileName().orElse(part.getName() + ".pdf")));
Files.copy(is, file);
return file;
} catch (IOException ioex) {
LOG.log(Level.WARNING, "Failed to process attachment part {0}", part);
return null;
}
}).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*******************************************************************
* Copyright (c) 2021 Eclipse Foundation
*
* This specification document is made available under the terms
* of the Eclipse Foundation Specification License v1.0, which is
* available at https://www.eclipse.org/legal/efsl.php.
*******************************************************************/
package jaxrs.examples.multipart;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.NotSupportedException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.EntityPart;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

@Path("/multipart")
public class MultipartResource {

private static final String PDF_ROOT_DIR = System.getProperty("pdf.root.dir", "/myPDFs");

@GET
@Produces(MediaType.MULTIPART_FORM_DATA)
public List<EntityPart> getAllPdfFilesInDirectory(@QueryParam("dirName") String dirName) throws IOException {
File dir = getDirectoryIfExists(dirName);
List<EntityPart> parts = new ArrayList<>();
for (File f : dir.listFiles()) {
parts.add(EntityPart.withFileName(f.getName()).content(new FileInputStream(f))
.mediaType("application/pdf")
.build());
}
return parts;
}

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response postNewPdfFiles(@QueryParam("dirName") String dirName, List<EntityPart> parts) throws IOException {
File dir = getDirectoryIfExists(dirName);
for (EntityPart p : parts) {
File f = new File(dir, p.getFileName().orElseThrow(BadRequestException::new));
if (f.exists()) {
throw new WebApplicationException(409); // 409 CONFLICT
}
try (InputStream content = p.getContent()) {
Files.copy(content, f.toPath());
}
}
return Response.ok().build();
}

@Path("/apply")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response applyForJob(@FormParam("name") String name,
@FormParam("recentPhoto") InputStream photoStream,
@FormParam("resume") EntityPart resume) {

String resumeFileName = resume.getFileName().orElseThrow(NotSupportedException::new);

if (resumeFileName.toLowerCase().endsWith(".pdf")) {
processPdfResume(resume.getContent());
} else {
// handle other file types, like Word docs, etc.
}

// process new application...
return Response.ok("Application received").build();
}

private File getDirectoryIfExists(String dirName) {
File dir = new File(PDF_ROOT_DIR, dirName);
if (!dir.exists()) {
throw new NotFoundException("dirName, " + dirName + ", does not exist");
}
return dir;
}

private void processPdfResume(InputStream is) {
// ...
}
}
Loading

0 comments on commit 48987b9

Please sign in to comment.