Propogate errors to UI with Spring 3 MVC / REST - rest

When /api/upload REST endpoint is accessed I have a UploadController that uses a service UploadService to upload a file to an ftp server with org.apache.commons.net.ftp.FTPClient. I would like to be able to send information back to the user if the ftp client was unable to connect or timed out, or successfully sent the file. I have some IOException handling, but I don't know how to turn that around and send it back to the front-end. Any help appreciated, thanks!
public void upload(InputStream inputStream) {
String filename = "file.txt"
client = new FTPClient();
try {
client.connect("ftpsite");
client.login("username", "password");
client.storeFile(filename, inputStream);
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (inputStream!= null) {
inputStream.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return null;
}

You should throw a new Exception in your catch statement.
For example, you could create a RequestTimeoutException class:
#ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
public class RequestTimeoutException extends RuntimeException { }
and then throw it when need be:
catch (IOException ioe) {
//do some logging while you're at it
throw new RequestTimeoutException();
}

Related

xmpp file upload using smack

i am unable to upload file on xmpp using smack client android. slot.puturl() returns "https://localhost:7443/httpfileupload/27c97df7-dbbf-47ff-b19a-3ac624e51cf0/1.jpg"
HttpFileUploadManager manager = HttpFileUploadManager.getInstanceFor(mConnection);
try {
Slot slot = manager.requestSlot(path, 10000);
uploadFileToSlot(new File(path), slot);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
I got solution for after very deep research.
That HttpFileUploadManager is only for requesting slot from server.
Once you got slot request url upload file using httpclient or okhttpclient.
For okhttpclient:
You need to configure sslSocketFactory by mtm or certificatepinning.
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient().newBuilder();
SSLContext sslContext = JavaPinning.forPin(<PINNING_VALUE>);
okHttpClientBuilder.writeTimeout(5, TimeUnit.MINUTES)
.connectTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES);
okHttpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), JavaPinning.trustManagerForPin(<PINNING_VALUE>));
OkHttpClient client = okHttpClientBuilder.build();
initiate okhttpclient and add file like.
Request request = new Request.Builder()
.url(slot.getPutUrl())
.put(RequestBody.create(MediaType.parse("application/octet-stream"), files))
.build();
Now lets begin to upload.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(final Call call, final IOException e) {
// Handle the error
Log.i(log, "error " + e);
}
#Override
public void onResponse(final Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
// Handle the error
Log.i(log, "errored " + response);
}
Log.i(log, "success " + response);
// Upload successful
}
});
Hope it helps you.

Does StreamingOutput in Jersey need to close?

I have a snippet to download a file from jersey 2.22,
StreamingOutput stream = (OutputStream os) -> {
try {
os.write( get a byte array here);
} catch (Exception e) {
LOGGER.error("Failed to fetch file, id:" + fileName, e);
throw new Exception());
}
};
the above code is working, but i'm wondering if the output stream I'm writing in needs to close.
I searched jersey's source code, in OutboundMessageContext
public void close() {
if(this.hasEntity()) {
try {
OutputStream e = this.getEntityStream();
e.flush();
e.close();
} catch (IOException var10) {
Logger.getLogger(OutboundMessageContext.class.getName()).log(Level.FINE, var10.getMessage(), var10);
} finally {
if(!this.committingOutputStream.isClosed()) {
try {
this.committingOutputStream.close();
} catch (IOException var9) {
Logger.getLogger(OutboundMessageContext.class.getName()).log(Level.FINE, var9.getMessage(), var9);
}
}
}
}
}
this method is to close entity stream. I'm not sure if this is the right close method working with StreamingOutput, can anyone help?

ConnectionPoolTimeoutException: timeout waiting for connection from pool

I have app that keep calling an api for json data, and pretty quickly i saw this 'Timeout waiting for connection from pool' exception, I googled around and found that's a connection leak caused by content not consumed, so i updated the code to close the inputstream after consume the jsondata, but still got those connection timeout exception, here is my code:
InputStream is = ApiUtil.getAsStream(Api.get(bookUrl).param("limit","500").param("bookId", bid).enable(Options.LongRunning), 3);
List<JsonBook> books = mapper.readValue(is, BOOK_TYPE);
is.close()
Api:
private JsonHttpClient client;
public APIForGet get(String endpoint) {
return new APIForGet(this.client, endpoint);
}
ApiUtil:
public static InputStream getAsStream(APIForGet get, Iterable<Long>retries) {
return get.asStream();
}
APIForGet:
private JsonHttpClient client;
public InputStream asStream() {
return this.client.getAsStream(this.hostname, this.port, this.endpoint, params, optionsArray());
}
JsonHttpClientImpl:
public InputStream getAsStream(Optional<String> host, Optional<Integer> port,String path, Multimap<String, String> param, Options ... options) {
HttpResponse reponse;
try {
response = request.execute();
if (response.isSuccessStatusCode()) {
return response.getContent();
}
} catch (Exception e) {
throw new Exception();
}
}
the wrapping logic here is kind of complicated, but eventually i think by closing the inputstream should work, any thoughts? Thanks!
try {
response = request.execute();
if (response.isSuccessStatusCode()) {
return response.getContent();
}
} catch (Exception e) {
throw new Exception();
}finally{
//TODO release conn or abort
}

Dynamic file loading in jetty

As per our implementation we are dynamically creating some image files in the server side and sharing the URLs.
But we are unable to retrieve the image resources using the URLs if the file is created while the JETTY is running.
However we can retrieve it if we stop the jetty and start it again.
I would like to know if there is any configuration which will enable us to retrieve the resources without the jetty being stopped?
Is it necessary to persist the dynamic images? If not, you can just stream the dynamic image like this:
public void sendImage(RenderedImage image, String mimeType, String imageIOType, HttpServletResponse response)
{
if(image != null)
{
OutputStream output = null;
try
{
output = response.getOutputStream();
response.setContentType(mimeType);
ImageIO.write(image, imageIOType, output);
}
catch (IOException e)
{
e.printStackTrace();
}
if(output != null)
{
try
{
output.flush();
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
HTH

linking my applet to a server dirctory to recieve or save a file from there?

I' m looking for a code to save the files created in a applet normally text files i want to save them on a server directory how can i do so.
Here is an example of how to send a String. In fact any Object can be sent this method so long as it's serializable and the same version of the Object exists on both the applet and the servlet.
To send from the applet
public void sendSomeString(String someString) {
ObjectOutputStream request = null;
try {
URL servletURL = new URL(getCodeBase().getProtocol(),
getCodeBase().getHost(),
getCodeBase().getPort(),
"/servletName");
// open the connection
URLConnection con = servletURL.openConnection();
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/octet-stream");
// send the data
request =
new ObjectOutputStream(
new BufferedOutputStream(con.getOutputStream()));
request.writeObject(someString);
request.flush();
// performs the connection
new ObjectInputStream(new BufferedInputStream(con.getInputStream()));
} catch (Exception e) {
System.err.println("" + e);
} finally {
if (request != null) {
try {
request.close();
} catch (Exception e) {
System.err.println("" + e);
};
}
}
}
To retrieve on the server side
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
try {
// get the input stream
ObjectInputStream inputStream = new ObjectInputStream(
new BufferedInputStream(request.getInputStream()));
String someString = (String)inputStream.readObject();
ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(response.getOutputStream()));
oos.flush();
// handle someString....
} catch (SocketException e) {
// ignored, occurs when connection is terminated
} catch (IOException e) {
// ignored, occurs when connection is terminated
} catch (Exception e) {
log.error("Exception", e);
}
}
No one is going to hand you this on a plate. You have to write code in your applet to make a socket connection back to your server and send the data. One way to approach this is to push the data via HTTP, and use a library such as commons-httpclient. That requires your server to handle the appropriate HTTP verb.
There are many other options, and the right one will depend on the fine details of the problem you are trying to solve.