I am printing a Pdf file via print services.
I implemented some code but it's not working - it throws the exception:
java.lang.RuntimeException: Cannot print a malformed PDF file
Please check my code and let me where I am going wrong.
internal class CustomPrintDocumentAdapter : PrintDocumentAdapter
{
private string filePath;
public CustomPrintDocumentAdapter(string filePath)
{
this.filePath = filePath;
}
public override void OnLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras)
{
if (cancellationSignal.IsCanceled)
{
callback.OnLayoutCancelled();
return;
}
callback.OnLayoutFinished(new PrintDocumentInfo.Builder(filePath)
.SetContentType(PrintContentType.Document)
.Build(), true);
}
public override void OnWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback)
{
try
{
using (InputStream input = new FileInputStream(filePath))
{
using (OutputStream output = new FileOutputStream(destination.FileDescriptor))
{
var buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.Read(buf)) > 0)
{
output.Write(buf, 0, bytesRead);
}
}
}
callback.OnWriteFinished(new[] { PageRange.AllPages });
}
catch (FileNotFoundException fileNotFoundException)
{
System.Diagnostics.Debug.WriteLine(fileNotFoundException);
}
catch (Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
}
}
Related
I am transforming an Image into pdf for test purposes.
To ensure that the Image is compatible with the printing process later on, I'm running a quick test print during the upload.
I'm creating a simple Test-PDF with a transformer. When I try to print an image with an incompatible format, the ImageManager of the transformer throws an ImageException, starting in the preloadImage() function:
public ImageInfo preloadImage(String uri, Source src)
throws ImageException, IOException {
Iterator iter = registry.getPreloaderIterator();
while (iter.hasNext()) {
ImagePreloader preloader = (ImagePreloader)iter.next();
ImageInfo info = preloader.preloadImage(uri, src, imageContext);
if (info != null) {
return info;
}
}
throw new ImageException("The file format is not supported. No ImagePreloader found for "
+ uri);
}
throwing it to:
public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager)
throws ImageException, IOException {
//Fetch unique version of the URI and use it for synchronization so we have some sort of
//"row-level" locking instead of "table-level" locking (to use a database analogy).
//The fine locking strategy is necessary since preloading an image is a potentially long
//operation.
if (isInvalidURI(uri)) {
throw new FileNotFoundException("Image not found: " + uri);
}
String lockURI = uri.intern();
synchronized (lockURI) {
ImageInfo info = getImageInfo(uri);
if (info == null) {
try {
Source src = session.needSource(uri);
if (src == null) {
registerInvalidURI(uri);
throw new FileNotFoundException("Image not found: " + uri);
}
info = manager.preloadImage(uri, src);
session.returnSource(uri, src);
} catch (IOException ioe) {
registerInvalidURI(uri);
throw ioe;
} catch (ImageException e) {
registerInvalidURI(uri);
throw e;
}
putImageInfo(info);
}
return info;
}
}
throwing it to :
public ImageInfo getImageInfo(String uri, ImageSessionContext session)
throws ImageException, IOException {
if (getCache() != null) {
return getCache().needImageInfo(uri, session, this);
} else {
return preloadImage(uri, session);
}
}
Finally it gets caught and logged in the ExternalGraphic.class:
/** {#inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
src = pList.get(PR_SRC).getString();
//Additional processing: obtain the image's intrinsic size and baseline information
url = URISpecification.getURL(src);
FOUserAgent userAgent = getUserAgent();
ImageManager manager = userAgent.getFactory().getImageManager();
ImageInfo info = null;
try {
info = manager.getImageInfo(url, userAgent.getImageSessionContext());
} catch (ImageException e) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageError(this, url, e, getLocator());
} catch (FileNotFoundException fnfe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageNotFound(this, url, fnfe, getLocator());
} catch (IOException ioe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageIOError(this, url, ioe, getLocator());
}
if (info != null) {
this.intrinsicWidth = info.getSize().getWidthMpt();
this.intrinsicHeight = info.getSize().getHeightMpt();
int baseline = info.getSize().getBaselinePositionFromBottom();
if (baseline != 0) {
this.intrinsicAlignmentAdjust
= FixedLength.getInstance(-baseline);
}
}
}
That way it isn't accessible for me in my code that uses the transformer.
I tried to use a custom ErrorListener, but the transformer only registers fatalErrors to the ErrorListener.
Is there any way to access the Exception and handle it myself without changing the code of the library?
It was easier than I thought. Before I call the transformation I register a costum EventListener to the User Agent of the Fop I'm using. This Listener just stores the Information what kind of Event was triggered, so I can throw an Exception if it's an ImageError.
My Listener:
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
public class ImageErrorListener implements EventListener
{
private String eventKey = "";
private boolean imageError = false;
#Override
public void processEvent(Event event)
{
eventKey = event.getEventKey();
if(eventKey.equals("imageError")) {
imageError = true;
}
}
public String getEventKey()
{
return eventKey;
}
public void setEventKey(String eventKey)
{
this.eventKey = eventKey;
}
public boolean isImageError()
{
return imageError;
}
public void setImageError(boolean imageError)
{
this.imageError = imageError;
}
}
Use of the Listener:
// Start XSLT transformation and FOP processing
ImageErrorListener imageListener = new ImageErrorListener();
fop.getUserAgent().getEventBroadcaster().addEventListener(imageListener);
if (res != null)
{
transformer.transform(xmlDomStreamSource, res);
}
if(imageListener.isImageError()) {
throw new ImageException("");
}
fop is of the type Fop ,xmlDomStreamSource ist the xml-Source I want to transform and res is my SAXResult.
i am using volley to fetch data from database.I always get null pointer error. I don't know whats the error. it always executes onErrorResponse() (error.null) and shows this in my logcat
BasicNetwork.performRequest: Unexpected response code 301
here is my java method to fetch data from php file .
private void fetchChatThread() {
StringRequest strReq = new StringRequest(Request.Method.POST,
EndPoints.chatMessages, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
Load_datato_list load_data_tolist = new Load_datato_list();
load_data_tolist.execute(obj);
} catch (JSONException e) {
Log.e(TAG, "json parsing error: " + e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Messages messages=new Messages();
error.printStackTrace();
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, " Try Again fetch error" + networkResponse);
Toast.makeText(Chat_Rooms.this, messages.getSender_id(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> myparams = new HashMap<String, String>();
try {
myparams.put("sender_userid", sender_userid);
myparams.put("reciver_id", String_username.reciver_user_id);
} catch (Exception e) {
e.printStackTrace();
}
Log.e(TAG, "Params: " + myparams.toString());
return myparams;
}
};
//Adding request to request queue
addToRequestQueue(strReq);
}
here is my private that loads data from php to objects
private class Load_datato_list extends AsyncTask<JSONObject, Void, ArrayList<Messages>> {
#Override
protected ArrayList<Messages> doInBackground(JSONObject[] params) {
JSONObject obj = params[0];
try {
JSONArray commentsObj = obj.getJSONArray("messages");
for (int i = 0; i < commentsObj.length(); i++) {
JSONObject commentObj = (JSONObject) commentsObj.get(i);
String commentId = commentObj.getString("id");
String commentText = commentObj.getString("message");
String createddate = commentObj.getString("date");
String commentuser_id = commentObj.getString("user_id_fk");
URL url;
Bitmap image, image1;
try {
url = new URL(Base_URL.BASE_URL_IMAGES + "user_profile_pictures" + commentuser_id + ".jpg");
image1 = BitmapFactory.decodeStream(url.openStream());
image = getResizedBitmap(image1, 50);
} catch (Exception e) {
image = null;
e.printStackTrace();
}
Users user;
user = new Users(commentuser_id, String_username.user_name, image);
Messages message = new Messages();
message.setId(commentId);
message.setMessage(commentText);
message.setCreatedAt(createddate);
message.setSender_id(commentuser_id);
message.setUser(user);
messageArrayList.add(message);
}
} catch (Exception e) {
e.printStackTrace();
}
return messageArrayList;
}
#Override
protected void onPostExecute(ArrayList<Messages> messageArrayList) {
Collections.reverse(messageArrayList);
chatroom_adapter.notifyDataSetChanged();
if (chatroom_adapter.getItemCount() > 1) {
rec_chatBubble.getLayoutManager().smoothScrollToPosition(rec_chatBubble, null, chatroom_adapter.getItemCount() - 1);
}
}
}
TRY THIS
private void fetchChatThread(final String count) {
StringRequest strReq = new StringRequest(Request.Method.POST,
EndPoints.chatMessages, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
Log.d("response error", response);
Load_datato_list load_data_tolist = new Load_datato_list();
load_data_tolist.execute(obj);
} catch (JSONException e) {
Log.e(TAG, "json parsing error: " + e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Messages messages = new Messages();
error.printStackTrace();
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, " Try Again fetch error" + networkResponse);
}
}) {
#Override
protected HashMap<String, String> getParams() {
HashMap<String, String> myparams = new HashMap<String, String>();
try {
myparams.put("sender_userid", sender_userid);
myparams.put("reciver_id", String_username.reciver_user_id);
myparams.put("count", count);
} catch (Exception e) {
e.printStackTrace();
}
Log.e(TAG, "Params: " + myparams.toString());
return myparams;
}
};
//Adding request to request queueok
addToRequestQueue(strReq);
}
AND THIS
private class Load_datato_list extends AsyncTask<JSONObject, Void, ArrayList<Messages>> {
#Override
protected ArrayList<Messages> doInBackground(JSONObject[] params) {
messageArrayList.clear();
JSONObject obj = params[0];
try {
JSONArray commentsObj = obj.getJSONArray("messages");
for (int i = 0; i < commentsObj.length(); i++) {
JSONObject commentObj = (JSONObject) commentsObj.get(i);
String Id = commentObj.getString("id");
String Text = commentObj.getString("message");
String date = commentObj.getString("date");
String yuser_id = commentObj.getString("user_id");
Messages message = new Messages();
message.setId(Id);
message.setMessage(Text);
message.setCreatedAt(date);
message.setSender_id(yuser_id);
messageArrayList.add(message);
}
} catch (Exception e) {
e.printStackTrace();
}
return messageArrayList;
}
I'm using nanohttpd in my native java code. When I use it normally everything looks good, but when I use jni library methods it does not work.
my app uses nanohttpd to make stream for mediaPlayer.
native methods:
public native String LH();
public native int P();
public native String EngineGS(Context context);
public native byte[] OGB(byte[] inputBuff);
variables :
private MediaPlayer mp;
private HTTPServer encryptServer;
nanohttpd class:
public class HTTPServer extends NanoHTTPD {
public HTTPServer(int port) throws IOException {
super(port);
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
}
#Override
public Response serve(IHTTPSession session) {
Response response = null;
try {
InputStream inputStream = new FileInputStream("/sdcard/Download/" + "encrypted.mp3");
byte[] encryptedInputByteArray = IOUtils.toByteArray(inputStream);
byte[] decryptedByteArray = OGB(encryptedInputByteArray);
inputStream = new ByteArrayInputStream(decryptedByteArray);
int totalLength = inputStream.available();
String requestRange = session.getHeaders().get("range");
if (requestRange == null) {
response = NanoHTTPD.newFixedLengthResponse(Response.Status.OK, "audio/mpeg", inputStream, totalLength);
} else {
Matcher matcher = Pattern.compile("bytes=(\\d+)-(\\d*)").matcher(requestRange);
matcher.find();
long start = 0;
try {
start = Long.parseLong(matcher.group(1));
} catch (Exception e) {
e.printStackTrace();
}
inputStream.skip(start);
long restLength = totalLength - start;
response = NanoHTTPD.newFixedLengthResponse(Response.Status.PARTIAL_CONTENT, "audio/mpeg", inputStream, restLength);
String contentRange = String.format("bytes %d-%d/%d", start, totalLength, totalLength);
response.addHeader("Content-Range", contentRange);
}
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
play method:
#ReactMethod
public void play() {
mp.getCurrentPosition();
try {
if (encryptServer == null) {
encryptServer = new HTTPServer(P());
}
Uri uri = Uri.parse(LH() + ":" + encryptServer.getListeningPort());
mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(getReactApplicationContext(), uri);
mp.prepare();
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
I do not know where the problem is.
Errors:
I think the problem comes from here:
No Content Provider: http://localhost:8080
How do I upload a file public and get link ? I am using Dropbox Java core api. Here.
public static void Yukle(File file) throws DbxException, IOException {
FileInputStream fileInputStream = new FileInputStream(file);
InputStream inputStream = fileInputStream;
try (InputStream in = new FileInputStream(file)) {
UploadBuilder metadata = clientV2.files().uploadBuilder("/"+file.getName());
metadata.withMode(WriteMode.OVERWRITE);
metadata.withClientModified(new Date());
metadata.withAutorename(false);
metadata.uploadAndFinish(in);
System.out.println(clientV2.files());
}
}
I use the following code to upload files to DropBox:
public DropboxAPI.Entry uploadFile(final String fullPath, final InputStream is, final long length, final boolean replaceFile) {
final DropboxAPI.Entry[] rev = new DropboxAPI.Entry[1];
rev[0] = null;
Thread t = new Thread(new Runnable() {
public void run() {
try {
if (replaceFile == true) {
try {
mDBApi.delete(fullPath);
} catch (Exception e) {
e.printStackTrace();
}
//! ReplaceFile is always true
rev[0] = mDBApi.putFile(fullPath, is, length, null, true, null);
} else {
rev[0] = mDBApi.putFile(fullPath, is, length, null, null);
}
} catch (DropboxException e) {
e.printStackTrace();
}
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return rev[0];
}
I want to upload files using spring-boot, and I have configured the properties right, and I also ensure the controller is correct, but the strange thing is the controller executed twice when I tried to upload a file larger exceed the limitation, what I expect is an error json message, and what I got is no response under the Postman.
Here is my controller,
#RestController
public class FileUploadController implements HandlerExceptionResolver {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);
private static final String UPLOAD_PATH = "upload";
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = "multipart/form-data", produces = "application/json;charset=UTF-8")
public String upload(final MultipartFile file) {
try {
final Result<String> result = new Result<>();
if (file.isEmpty()) {
result.setSuccess(false);
result.setMessage("file is empty");
return Constants.OBJECT_MAPPER.writeValueAsString(result);
}
final File outputFile = new File(UPLOAD_PATH, UUID.randomUUID().toString());
FileUtils.writeByteArrayToFile(outputFile, file.getBytes());
result.setSuccess(true);
result.setMessage(outputFile.toString());
return Constants.OBJECT_MAPPER.writeValueAsString(result);
} catch (final Exception ex) {
LOGGER.error(ex.getMessage(), ex);
return ExceptionResultBuilder.build(ex);
}
}
#Override
public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) {
final ModelAndView modelAndView = new ModelAndView();
modelAndView.setView(new MappingJackson2JsonView());
final Map<String, Object> map = new HashMap<>();
map.put("success", false);
if (ex instanceof MultipartException) {
// if (LOGGER.isDebugEnabled()) {
LOGGER.info(ex.getMessage(), ex);
// }
final Throwable rootCause = ((MultipartException) ex).getRootCause();
if (rootCause instanceof SizeLimitExceededException) {
map.put("message", "request too large");
} else if (rootCause instanceof FileSizeLimitExceededException) {
map.put("message", "file too large");
} else {
map.put("message", "其他异常: " + rootCause.getMessage());
}
} else {
LOGGER.error(ex.getMessage(), ex);
}
modelAndView.addAllObjects(map);
return modelAndView;
}
}
and this is my property snippet for file uploading,
# MULTIPART (MultipartProperties)
multipart.enabled=true
multipart.max-file-size=5Mb
multipart.max-request-size=10Mb
If I tried to upload a file a bit larger than 5M, I will get the result like below under Postman, (the file size is 5208k)
enter image description here
and if I tried to upload a file between 5M and 10M, I will get this error, (the file size is 9748k)
enter image description here
I debugged into the controller and found that the resolveException method executed twice in a single upload.
Does anybody give me some tip?
The latest code list here, and I still got the same result,
#RestController
#ControllerAdvice
public class FileUploadController {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);
private static final String UPLOAD_PATH = "upload";
#RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = "multipart/form-data", produces = "application/json;charset=UTF-8")
public HttpEntity<?> upload(final MultipartFile file) {
try {
final Result<String> result = new Result<>();
if (file == null || file.isEmpty()) {
result.setSuccess(false);
result.setMessage("上传的文件为空");
return new ResponseEntity<Result<?>>(result, HttpStatus.OK);
}
final File outputFile = new File(UPLOAD_PATH, UUID.randomUUID().toString());
FileUtils.writeByteArrayToFile(outputFile, file.getBytes());
result.setSuccess(true);
result.setMessage(outputFile.toString());
return new ResponseEntity<Result<?>>(result, HttpStatus.OK);
} catch (final Exception ex) {
LOGGER.error(ex.getMessage(), ex);
return ExceptionResultBuilder.build(ex);
}
}
#ExceptionHandler(MultipartException.class)
public HttpEntity<?> multipartExceptionHandler(final MultipartException exception) {
LOGGER.error(exception.getMessage(), exception);
try {
final Result<String> result = new Result<>();
result.setSuccess(false);
final Throwable rootCause = ((MultipartException) exception).getRootCause();
if (rootCause instanceof SizeLimitExceededException) {
result.setMessage("请求过大");
} else if (rootCause instanceof FileSizeLimitExceededException) {
result.setMessage("文件过大");
} else {
result.setMessage("未知错误");
}
return new ResponseEntity<Result<?>>(result, HttpStatus.OK);
} catch (final Exception ex) {
LOGGER.error(ex.getMessage(), ex);
return ExceptionResultBuilder.build(ex);
}
}
}
I just go the same error and fix it by add the flowing code to my controller, good luck
#ExceptionHandler({ MultipartException.class, FileSizeLimitExceededException.class,
SizeLimitExceededException.class })
public ResponseEntity<Attachment> handleUploadrException(HttpServletRequest request, Throwable ex) {
Attachment result = new Attachment();
result.setDescription(ex.getMessage());
HttpStatus status = getStatus(request);
return new ResponseEntity<Attachment>(result, status);
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}