Multipart image upload issue in Codename One - codenameone
I am using this code to upload an image. It works on emulator but always fail on Android device (OS 6.0)
My code is
`private void uploadImage3(final String imagePath, String id){
final Hashtable htArg = new Hashtable();
htArg.put("pk1value", id);
htArg.put("pk2value", "");
htArg.put("pk3value", "");
htArg.put("datatype", "6");
htArg.put("module", "");
htArg.put("action", "");
try {
htArg.put("thefile", FileSystemStorage.getInstance().openInputStream(imagePath));
} catch (IOException ex) {
Log.p("imgRequest.Error = " + ex.toString());
}
htArg.put("submit", "Submit");
final String boundary = "-----------------------------0123456789012";
MultipartRequest request = new MultipartRequest(){
#Override
protected void buildRequestBody(OutputStream os) throws IOException {
Writer writer = null;
writer = new OutputStreamWriter(os, "UTF-8");
String CRLF = "\r\n";
boolean canFlushStream = true;
Enumeration e = htArg.keys();
while(e.hasMoreElements()) {
if (shouldStop()) {
break;
}
String key = (String)e.nextElement();
Object value = htArg.get(key);
writer.write("--");
writer.write(boundary);
writer.write(CRLF);
if(value instanceof String) {
writer.write("Content-Disposition: form-data; name=\""+key+"\"");
writer.write(CRLF);
writer.write(CRLF);
writer.write(CRLF);
if(canFlushStream){
writer.flush();
}
writer.write(Util.encodeBody((String)value));
if(canFlushStream){
writer.flush();
}
}else {
writer.write("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + key +"\"");
writer.write(CRLF);
writer.write("Content-Type: ");
writer.write("image/jpeg");
writer.write(CRLF);
writer.write("Content-Transfer-Encoding: binary");
writer.write(CRLF);
writer.write(CRLF);
if(canFlushStream){
writer.flush();
}
InputStream i;
if (value instanceof InputStream) {
i = (InputStream)value;
byte[] buffer = new byte[8192];
int s = i.read(buffer);
while(s > -1) {
os.write(buffer, 0, s);
if(canFlushStream){
writer.flush();
}
s = i.read(buffer);
}
// (when passed by stream, leave for caller to clean up).
if (!(value instanceof InputStream)) {
Util.cleanup(i);
}
} else {
os.write((byte[])value);
}
value = null;
if(canFlushStream){
writer.flush();
}
}
writer.write(CRLF);
if(canFlushStream){
writer.flush();
}
}
writer.write("--" + boundary + "--");
writer.write(CRLF);
if(canFlushStream){
writer.flush();
}
writer.close();
}
#Override
protected void readResponse(InputStream input) {
try {
Result result = Result.fromContent(input, Result.XML);
Log.p("imgRequest response: " + result.toString());
} catch (Exception ex) {
Log.p("imgRequest.Error = " + ex.toString());
ex.printStackTrace();
}
}
#Override
protected void handleErrorResponseCode(int code, String message) {
Log.p("handleErrorResponseCode = "+code + ":" + message);
}
#Override
protected void handleException(Exception err) {
Log.p("handleException = "+err.toString());
err.printStackTrace();
}
};
String theURL = Application.getCurrentConnection().get("URL").toString() + "/W1Servlet";
request.setUrl(theURL+"/uploadfiledebug");
request.setBoundary(boundary);
request.setPost(true);
try {
//need to keep this code as it will calculate file size internally
// and also have to add thefile separately in myArgHashTable
request.addData("thefile", imagePath, "image/jpeg");
request.setFilename("thefile", "img.jpeg");
} catch (Exception ex) {
}
InfiniteProgress prog = new InfiniteProgress();
Dialog dlg = prog.showInifiniteBlocking();
request.setDisposeOnCompletion(dlg);
NetworkManager.getInstance().addToQueueAndWait(request);
}`
The traced error on real device is,
`java.net.ProtocolException: exceeded content-length limit of 11076 bytes
at com.android.okhttp.internal.http.RetryableSink.write(RetryableSink.java:58)
at com.android.okhttp.okio.RealBufferedSink.close(RealBufferedSink.java:234)
at com.android.okhttp.okio.RealBufferedSink$1.close(RealBufferedSink.java:209)
at com.codename1.impl.CodenameOneImplementation.cleanup(CodenameOneImplementation.java:4385)
at com.codename1.impl.android.AndroidImplementation.cleanup(AndroidImplementation.java:4579)
at com.codename1.io.Util.cleanup(Util.java:149)
at com.codename1.io.BufferedOutputStream.close(BufferedOutputStream.java:287)
at com.codename1.impl.CodenameOneImplementation.cleanup(CodenameOneImplementation.java:4385)
at com.codename1.impl.android.AndroidImplementation.cleanup(AndroidImplementation.java:4579)
at com.codename1.io.ConnectionRequest.performOperation(ConnectionRequest.java:804)
at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:282)
at com.codename1.impl.CodenameOneThread$1.run(CodenameOneThread.java:60)
at java.lang.Thread.run(Thread.java:818)`
I am not sure what I am missing.
Please someone can help me.
Thanks
Updated Code
`private void uploadImage4(final String imagePath, String id){
MultipartRequest request = new MultipartRequest(){
#Override
protected void readResponse(InputStream input) throws IOException {
try {
Result result = Result.fromContent(input, Result.XML);
if(isDebugOn){
Application.writeInDebugFile(debugFileName,
"result.toString(): "+ result.toString());
}
Log.p("imgRequest response: " + result.toString());
} catch (Exception ex) {
Log.p("imgRequest.Error = " + ex.toString());
ex.printStackTrace();
if(isDebugOn){
Application.writeInDebugFile(debugFileName,
"readResponse.Exception: "+ex.toString());
}
}
}
};
String theURL = Application.getCurrentConnection().get("URL").toString() + "/W1Servlet";
request.setUrl(theURL+"/uploadfiledebug");
request.addArgument("entityname", "RCV_HEADERS");
request.addArgument("category", "37");
request.addArgument("description", "Uploaded by More4Apps Mobile App");
request.addArgument("pk1value", id);//this is used as a primary key
request.addArgument("pk2value", "");
request.addArgument("pk3value", "");
request.addArgument("datatype", "6");
request.addArgument("module", "");
request.addArgument("action", "");
request.addArgument("submit", "Submit");
try {
//add the data image
request.addData("thefile", imagePath, "image/jpeg");
request.setFilename("thefile", "img.jpeg");
} catch (IOException ex) {
Log.p("Error:"+ ex.toString());
}
request.setPriority(ConnectionRequest.PRIORITY_CRITICAL);
NetworkManager.getInstance().addToQueue(request);
}`
And new error is:
`<ERROR_MESSAGE>IO Error:com.more4apps.mobile.ActionUploadFileoracle.ord.im.OrdHttpUploadException: IMW-00106: the end-of-headers delimiter (CR-LF) was not present
IMW-00112: additional error information: Content-Type: text/plain; charset=UTF-8IMW-00106: the end-of-headers delimiter (CR-LF) was not present
IMW-00112: additional error information: Content-Type: text/plain; charset=UTF-8
oracle.ord.im.OrdMultipartParser.doParse(OrdMultipartParser.java:312)
oracle.ord.im.OrdMultipartParser.parseFormData(OrdMultipartParser.java:150)
oracle.ord.im.OrdHttpUploadFormData.parseFormData(OrdHttpUploadFormData.java:532)
com.more4apps.mobile.ActionUploadFile.performAction(ActionUploadFile.java:39)
com.more4apps.mobile.W1Servlet.processAction(W1Servlet.java:449)
com.more4apps.mobile.W1Servlet.doPost(W1Servlet.java:248)
javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:64)
oracle.apps.jtf.base.session.ReleaseResFilter.doFilter(ReleaseResFilter.java:26)
com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:15)
oracle.apps.fnd.security.AppsServletFilter.doFilter(AppsServletFilter.java:318)
com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:642)
com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:391)
com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:908)
com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:458)
com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:313)
com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:199)
oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)
com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
java.lang.Thread.run(Thread.java:682)</ERROR_MESSAGE>`
If you override buildRequestBody in a multipart request you effectively disable its functionality...
All of that code is incorrect and shouldn't be there. Multipart will work for large files by default.
Related
I get an transformClassesWithRealmTransformerForDebug error
This is the error that I get: Error: Execution failed for task ':passenger:transformClassesWithRealmTransformerForDebug'. javassist.CannotCompileException: updateVehicle (Landroid/content/Context;Ljava/lang/Integer;Lnl/hgrams/passenger/model/Vehicle;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lnl/hgrams/passenger/interfaces/JsonCallback;)V in nl.hgrams.passenger.model.UserVehicle: failed to resolve types Now I seen that the latest versions of Realm do support having functions inside the realmObject. I have this function inside that causes the crash: public void updateVehicle(Context context, Integer userID, Vehicle newVehicle, Integer vclass, String newCountry, String newLicense, String newImage, List<MileageRates> mileageRates, final JsonCallback jsonCallback) { try{ JSONObject params = createJsonForUpdate(context,newVehicle, vclass, newCountry, newLicense, newImage, mileageRates); Log.i("","vehicle params is:" + params.toString()); WSCalls.sendData(Request.Method.POST, Constants.API_ENDPOINT + "/users/" + userID + "/vehicles/" + id + "/update", params , context, null, true, new JsonCallback() { #Override public void onResponse(JSONObject jsonObject, VolleyError error, String errorMsg) { if(jsonCallback != null) jsonCallback.onResponse(jsonObject,error,errorMsg); } }); }catch (Exception e){ Log.e("","error updating vehicle:" + e.getMessage()); } } IF I comment out WScall.sendData, then it will work. This is the method: public static void sendData(final Integer type , final String url, final JSONObject params, final Context context, final View loader, boolean hasAllURL , final JsonCallback listener){ String URL = Constants.API_ENDPOINT + url; if(hasAllURL){ URL = url; } final String URL2 = URL; Log.i(TAG, "test offline sendData - url:: " + URL); if(params != null) { Log.i(TAG, "test offline sendData - params: " + params.toString()); } JsonObjectRequest jr = new JsonObjectRequest(type, URL, params, new Response.Listener<JSONObject>() { #Override public void onResponse(JSONObject response) { Log.i(TAG, "sendData Response: " + response.toString()); Utils.logWSResponse("POST", URL2, 200, response.toString(), header); try{ if(Utils.WSValidator(response)){ if(loader!= null) loader.setVisibility(View.GONE); if(listener != null) listener.onResponse(response, null, null); }else{ if(listener != null) listener.onResponse(response,null, null); Log.i("","test offline data:" + response.toString()); Utils.appendLog("send data response not VALID",true); } }catch (Exception e){ Utils.appendLog("send data error: " + e.getMessage(),true); Log.e(TAG, "JsonException: " + e.getMessage()); } } }, new Response.ErrorListener() { #Override public void onErrorResponse(VolleyError error) { String json = null; if(loader!= null) loader.setVisibility(View.GONE); if(error != null && error.networkResponse != null) { Utils.appendLog("WSCALL send data done, ERROR stop STATUS CODE" + error.networkResponse.statusCode, true); json = new String(error.networkResponse.data); json = trimMessage(json, "message"); if (json != null) { Utils.logWSResponse("POST", URL2, error.networkResponse.statusCode, json, header); } Log.i(TAG, "checkout valid send data Volley error response: " + json); if(error.networkResponse.statusCode == 401 && PSLocationCenter.getInstance().pref.getAuthenticationToken() != null){ PSLocationCenter.getInstance().pref.setFbConnected(context, false); if(PSSocialService.getInstance().fbSession != null){ PSSocialService.getInstance().fbSession.closeAndClearTokenInformation(); } PSUserService.getInstance(context).finishLogOut(); return; } } if(listener != null) listener.onResponse(null, error, json); } }){ #Override public Map<String, String> getHeaders() throws AuthFailureError { PassengerPreferencesManager pref = new PassengerPreferencesManager(context); if(pref.getAuthenticationToken() != null){ return getHeaderData(pref, context); }else{ return super.getHeaders(); } } }; if (Utils.networkIsAvailable( context)) { try{ header = jr.getHeaders().toString(); Utils.logWSRequest("POST", URL, params.toString() ,header); }catch (Exception e){ Log.e("","error volley: " + e.getMessage()); } jr.setRetryPolicy(new DefaultRetryPolicy(60 * 1000, 0, 1)); PSLocationCenter.getInstance().mRequestQueue.add(jr); } else { if(loader!= null) loader.setVisibility(View.GONE); Log.i(TAG, "sendData - no internet"); AlertDialog.show(context, "", context.getString(R.string.no_internet), context.getString(R.string.OK), null); } } Can this be fixed? or it does not support that method cause of nonrealm objects in it? I tried to add a nonrealm object inside and it worked. Also, Another question. can I add inside my realmObject Integers that I don't want to be added to the db. Values that I use in functions, so that I do not need to call a realm transaction every time I use them?
I have the URL like this: Constants.API_ENDPOINT + "/users/" + userID + "/vehicles/" + id + "/update" If I set getId() instead of simply the variable, it works
How to take screen shot for the Failed Tests only after 'Retry'
In our current framework we are taking screenshots onTestFailure. And now we have implemented 'IRetryAnalyzer' using which are re-running the failed tests. Here when the test fails for the first time, it is taking the screen shot and keeping it in a folder which indicates 'Failed Test', which may get passed in the next attempt. When we submit final Automation report, we need to submit screenshots also. In Screenshots folder, currently passed (after re-running) test images are also attached. Can we take a screenshot only when the Test has failed Even After Re-running by ignoring the previous test fails. Please suggest if there is any other alternative. Below is the code for Retry #Override public boolean retry(ITestResult result) { boolean iFlag=false; String resultString = result.getThrowable().toString(); //Checking for specific reason of failure if (resultString.contains("NoSuchElementException") || resultString.contains("TimeoutException") ) { if (retryCount < maxRetryCount) { System.out.println("Retrying " + result.getName()+ " test for the "+ (retryCount + 1) + " time(s)."); retryCount++; iFlag=true; } } else { //making retryCount and maxRetryCount equal retryCount=0; maxRetryCount=0; iFlag=false; } return iFlag; } Below is the code for On Test failure private static int retryCount=0; private static int maxRetryCount=1; #Override public void onTestFailure(ITestResult result) { System.out.println("***** Error "+result.getName()+" test has failed *****"); String methodName=result.getName().toString().trim(); //takeScreenShot(methodName); driver=TestBase.getDriver(); if( driver != null && retryCount == maxRetryCount) { takeScreenShot(driver, methodName); } }
Try to put both onTestFailure/AfterMethod and retry methods in same class like Retry or any suitable name. And there you can define your methods as: private static int retryCount = 0; private static int maxRetryCount = 2; #AfterMethod public void tearDown(ITestResult result) throws IOException { String methodname = result.getName(); WebDriver augmentedDriver = new Augmenter().augment(driver); try { if (driver != null && ((RemoteWebDriver) driver).getSessionId() != null && !result.isSuccess() && retryCount == maxRetryCount) { File scrFile = ((TakesScreenshot) augmentedDriver) .getScreenshotAs(OutputType.FILE); FileUtils.copyFile(scrFile, new File(("./test-output/archive/" + "screenshots/" + methodname + "_" + System.currentTimeMillis() + ".png"))); } } catch (Exception e) { e.printStackTrace(); } finally { driver.quit(); } } #Override public boolean retry(ITestResult result) { boolean res = false; try { if (result.getThrowable().toString() .contains("NoSuchElementException")) { if (retryCount < maxRetryCount) { retryCount++; res = true; } else if (retryCount == maxRetryCount) { retryCount = 0; res = false; } } else { retryCount = 0; } return res; } catch (Exception e) { return false; } }
Customizing DBTrigger message in adf
Hi I am trying to customize DBTrigger message in bean Here is code for it, it is displaying my customized message but as well it is displaying DBTrigger message below to my message, Kindly help me to get out of this. public void saveLataActionListenerNew(ActionEvent actionEvent) { System.out.println("----on click saved "); try { OperationBinding operationBinding = (OperationBinding)getBindings().getOperationBinding("Commit"); Object result = operationBinding.execute(); System.out.println("Errors : " + operationBinding.getErrors()); if (operationBinding.getErrors() != null) { Iterator it = operationBinding.getErrors().iterator(); System.out.println("error = " + it); System.out.println("size of Errors - " + operationBinding.getErrors().size()); while (it.hasNext()) { DMLException error = (DMLException)it.next(); String errorCause = "" + error.getCause(); System.out.println("error.getCause() : " + errorCause); if (errorCause != null && errorCause.contains("ORA-00001: unique constraint")) { uniqueConstraint = "Lata is Exists for given State"; showMessage(uniqueConstraint, FacesMessage.SEVERITY_ERROR); return; } } } uniqueConstraint = "Record is saved successfully"; showMessage(uniqueConstraint, FacesMessage.SEVERITY_INFO); System.out.println("---record saved successfully"); // addPlaceCodePfl.setRendered(false); // addPlaceCodePgl.clearInitialState(); // addPlaceCodePfl. } catch (Exception e) { uniqueConstraint = e.getMessage(); showMessage(uniqueConstraint, FacesMessage.SEVERITY_ERROR); e.printStackTrace(); }
getting an empty file when downloading : jsf
I want to download a file stored in system directory but when downloading the file in jsf page I get it empty. This is my xhtml page : <h:form> <h:commandButton value="Download" action="#{helloBean.downloadFile}" /> </h:form> and my managed bean : #ManagedBean #SessionScoped public class HelloBean { public void downloadFile() { File file = new File("C:\\data\\contacts.doc"); HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); response.setHeader("Content-Disposition", "attachment;filename=contacts.doc"); response.setContentLength((int) file.length()); ServletOutputStream out = null; try { FileInputStream input = new FileInputStream(file); byte[] buffer = new byte[1024]; out = response.getOutputStream(); int i = 0; while ((i = input.read(buffer)) != -1) { out.write(buffer); out.flush(); } FacesContext.getCurrentInstance().getResponseComplete(); } catch (IOException err) { err.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (IOException err) { err.printStackTrace(); } } } } so How to solve it? Thanks in advance.
I think this code solve your problem. public void download() throws IOException { FacesContext context = FacesContext.getCurrentInstance(); HttpServletResponse response = (HttpServletResponse) context .getExternalContext().getResponse(); File file = new File(filePath); if (!file.exists()) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } response.reset(); response.setBufferSize(DEFAULT_BUFFER_SIZE); response.setContentType("application/octet-stream"); response.setHeader("Content-Length", String.valueOf(file.length())); response.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\""); BufferedInputStream input = null; BufferedOutputStream output = null; try { input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE); output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE); byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; int length; while ((length = input.read(buffer)) > 0) { output.write(buffer, 0, length); } } finally { input.close(); output.close(); } context.responseComplete(); }
loading image to jsp (struts2) from database
I have problem with loading image from database to jsp view. It looks like action are execute but stop in middle. I log when execute() method start and when its end. In log file i can see start this method but there are no end. I have action: public class ShowImageAction extends BaseAction { private static final long serialVersionUID = 1L; private static final Log LOG = LogFactory.getLog(ShowImageAction.class); private int id; public String execute() { LOG.info("Enter execute()"); MessageBean messageBean = (MessageBean) sessionParameters .get(SessionParameters.BANNER_EDIT); IFiles filesEJB = EJBLocator.getFiles(); if (messageBean != null) { id = messageBean.getBannerId(); } FileBean file = filesEJB.file(id); LOG.info("Id = " + id); if (file != null) { byte[] bytes = null; try { LOG.info("File: name = " + file.getName() + ". type = " + file.getType()); if (file.getImage() != null) { bytes = FileUtils.readFileToByteArray(file.getImage()); HttpServletResponse response = ServletActionContext .getResponse(); response.setContentType(file.getType()); OutputStream out = response.getOutputStream(); out.write(bytes); out.close(); } else { LOG.info("execute(): Nie udało się pobrać pliku z bazy danych!"); } } catch (IOException e) { LOG.error(e); } } else { LOG.info("execute(): Nie udało się pobrać pliku z bazy danych!"); } LOG.info("Exit execute()"); return NONE; } jsp: <div class="OneFilteringRow"> Podgląd<br /> <img src="/ebok-bm/ShowImageAction" alt="Podgląd banera" /> </div> struts.xml <action name="ShowImageAction" class="pl.bm.action.content.ShowImageAction"> </action>
Problem was in: FileBean file = filesEJB.file(id); I get bytes from database and try to save it to tmpFile. Now I get bytes and writes them to a temporary file and immediately transmit it to the action and everything is ok. Now I have: FileBean file = filesEJB.file(id); LOG.info("Id = " + id); if (file != null) { byte[] bytes = null; try { LOG.info("File: name = " + file.getName() + ". type = " + file.getType()); if (file.getImage() != null) { **bytes = file.getImage();** HttpServletResponse response = ServletActionContext .getResponse(); response.setContentType(file.getType()); OutputStream out = response.getOutputStream(); out.write(bytes); out.close(); } else { LOG.info("execute(): Nie udało się pobrać pliku z bazy danych!"); } } catch (IOException e) { LOG.error(e); } }
Switch to your own result implements Result class and write output here.Other in struts.xmlaction result type specified own with approx mate parameters. refer:generate own image as action result