Причина дублирования, как упоминалось в ответе Марка , заключается в том, что вы создаете «временный» файл при создании и записи в 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 = "hi
";
renderer.setDocumentFromString(yourXhtmlContentAsString);
renderer.layout();
renderer.createPDF(output);
output.flush();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
return Response.ok(entity)
.header(...)
.build();
}
Ваш вспомогательный метод - самый чистый способ сделать это, ИМО. Если вы передадите список или массив, то недобросовестный фрагмент кода может преобразовать его и изменить содержимое, что в некоторых ситуациях приведет к странному поведению. Вы можете использовать коллекцию только для чтения, но это, вероятно, потребует еще большей упаковки. Я считаю, что ваше решение настолько изящно, насколько возможно.
Я немного удивлен, что никто не предложил новую перегрузку метода с аргументом типа T для упрощения клиентского API.
public void DoSomething<T>(IEnumerable<T> list)
{
// Do Something
}
public void DoSomething<T>(T item)
{
DoSomething(new T[] { item });
}
Теперь ваш клиентский код может просто делать это:
MyItem item = new MyItem();
Obj.DoSomething(item);
или со списком:
List<MyItem> itemList = new List<MyItem>();
Obj.DoSomething(itemList);
Либо (как было сказано ранее)
MyMethodThatExpectsAnIEnumerable(new[] { myObject });
, либо
MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(myObject, 1));
В качестве примечания, последняя версия также может быть полезной, если вам нужен пустой список анонимных объектов, например
var x = MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(new { a = 0, b = "x" }, 0));
В C # 3 (я знаю, что вы сказали 2) вы можете написать общий метод расширения, который может сделать синтаксис немного более приемлемым: тогда
static class IEnumerableExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
yield return item;
}
}
клиентский код будет элементом. ToEnumerable ()
.
Что ж, если метод ожидает IEnumerable
, вам нужно передать что-то, что является списком, даже если он содержит только один элемент.
передача
new T[] { item }
] в качестве аргумента я думаю
В C# 3.0 вы можете использовать класс System.Linq.Enumerable:
// using System.Linq
Enumerable.Repeat(item, 1);
Это создаст новый IEnumerable, который будет содержать только ваш элемент.
. Я бы сказал, что самый простой способ - new T [] {item};
; для этого нет синтаксиса. Ближайший эквивалент, который я могу придумать, - это ключевое слово params
,