Каждая функция контекста выполнения в javascript имеет контекст контекста этот параметр , который задается:
Каким бы ни был этот контекст области видимости, ссылается на «this».
Вы можете изменить это значение для параметра этого контекста области , используя func.call
, func.apply
или func.bind
.
По умолчанию и что сбивает с толку большинство новичков, когда вызывающий вызывающий вызов вызывается после того, как событие добавлено в элемент DOM, контекст области это значение функции является элементом DOM.
jQuery делает это тривиальным для изменения с помощью jQuery.proxy.
Проблема
В своем коде вы генерируете файл, который затем будет обслуживаться вашим API. Этот файл создается с помощью new java.io.FileOutputStream(filePath)
и называется Resume2019-01-16.pdf
в папке Downloads
.
Поскольку вы используете свой API локально, при переходе к конечной точке браузер загрузит файл, который вы обслуживаете, в вашу папку Downloads
. Поскольку Resume2019-01-16.pdf
уже существует, браузер назовет его Resume2019-01-16 (1).pdf
.
Следовательно, похоже, что два файла загружаются, но один генерируется вашим кодом, а другой - фактически загружен.
Исправить
Измените папку для файлов, которые вы обслуживаете, и в вашем Downloads
появятся только фактически загруженные файлы, например:
String filePath = homePath + "/Documents/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";
[ 1115] В качестве альтернативы используйте некоторый метод для сохранения вашего файла в памяти, вместо создания физического файла, и используйте его вместо этого.
Причина дублирования, как упоминалось в ответе Марка , заключается в том, что вы создаете «временный» файл при создании и записи в FileOutputStream
.
Решение: вам не нужно создавать временный файл для загрузки. Вместо создания FileOutputStream
, просто используйте StreamingOutput
и передайте StreamingOutput
OutputStream
методу ITextRenderer#createPDF(OutputStream)
.
@GET
@Produces("application/pdf")
public Response getResumePdf(@PathParam("userId") String userId) {
StreamingOutput entity = new StreamingOutput() {
@Override
public void write(OutputStream output) {
try {
ITextRenderer renderer = new ITextRenderer();
String yourXhtmlContentAsString = "<h1>hi </h1>";
renderer.setDocumentFromString(yourXhtmlContentAsString);
renderer.layout();
renderer.createPDF(output);
output.flush();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
return Response.ok(entity)
.header(...)
.build();
}
Вы должны использовать StreamingOutput вместо использования File.
String homePath = System.getProperty("user.home");
String filePath = homePath + "/Downloads/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";
org.xhtmlrenderer.pdf.ITextRenderer renderer = new ITextRenderer();
String yourXhtmlContentAsString = "<h1>hi </h1>";
renderer.setDocumentFromString(yourXhtmlContentAsString);
renderer.layout();
java.io.FileOutputStream fos = new java.io.FileOutputStream(filePath);
renderer.createPDF(fos);
//fos.close();
final File file = new File(filePath);
StreamingOutput fileStream = new StreamingOutput()
{
@Override
public void write(java.io.OutputStream output) throws IOException, WebApplicationException
{
try
{
byte[] data = Files.readAllBytes(file.toPath());
output.write(data);
output.flush();
}
catch (Exception e)
{
throw new WebApplicationException("File Not Found. !!");
}
}
};
return Response
.ok( fileStream, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"Resume" + LocalDateTime.now().toLocalDate() + ".pdf\"")
.build();