Android app with python backend - java

Hey I created a neural network using python, this network can recognize handwritten digits. I want to use this in my android app. The android app will take a picture of a hand written digit, and send it to the neural network, the neural network will figure out the digit and send it back to the app. How would I do this? I looked at Google Cloud Platform, but I am confused. I want to know how I will send the picture from the app to my python neural network, and send the output back.

Make yourself familiar with the concepts of REST (RestEasy, Jersey,...), create a REST server with an endpoint that can receive a JSON string which contains your base64 picture. The app converts the picture with base64 and sends it to the REST server. Unencode it in your REST server, delegate it to the python script, convert the result back to JSON and send it back to the app. The app itself receives the JSON and gets the data from it.
This is how I would do it with WildFly server and RestEasy:
//app side
PictureInputBo pictureInputBo = new PictureInputBo([your binary]); //encodes it to base64
//This is working Java code and can be used.
//It will automatically convert to JSON and sent to the "convert" endpoint of the server
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("http://yourserver:8080/your-webservice/rest/convert/");
Response response = target.request().accept(MediaType.APPLICATION_JSON).post(Entity.entity(pictureInputBo, "application/json;charset=UTF-8;version=1"));
//Server side..."Converter Endpoint", this is also working Java code.
//it will automatically converted back to the Java object "PictureInputBo" by RestEasy
#POST
#Path("/convert")
#Consumes(MediaType.APPLICATION_JSON)
public Response convertPicture(#NotNull(message = "Must not be null") #Valid PictureInputBo inputBo)
{
//Here you pass your business object to the converter service which processes the data
//(pass it to python or whatever)
PictureOutputBo result = converterService.convert(inputBo);
//Resteasy converts it back to JSON and responds it to the app.
return Response.ok().entity(result).build();
}
//Back in your app.
check if response.getStatus() == 200) //HTTP Status OK
PictureOutputBo pictureOutputBo = response.readEntity(PictureOutputBo.class);

Related

Amazon S3 AWS SDK [Java] - MultiPart Upload how to get a custom header in the http response?

how can I access a custom header from a server response when using TransferManager ?
we have a custom header added in the response from our server, from the client side we use multi part upload with default transfer manager
any suggestion how in how i could hook up it ?
so basically i want to pass over the response from the return response.getAwsResponse(); found in the class: AmazonS3Client on the method
private <X, Y extends AmazonWebServiceRequest> X invoke(Request<Y> request,
HttpResponseHandler<AmazonWebServiceResponse<X>> responseHandler,
String bucket, String key, boolean isAdditionalHeadRequestToFindRegion) {
that response will have the HTTP response from the server containing the custom heather which I'm after, basically is a unique Id send back when the file was 100% completed so than i can manipulate it.
I need to pass over this custom header from the response to the very beginning where I use the transfer manager and the upload.waitForCompletion(),
also i don't want to edit the amazon's,
so does anyone know if there is an interface or some other object which provides me access to it ?
After some debug into the framework I strongly believe that there is no way to have access to the http response when using the TransferManager
for what we are trying to do we need to send an unique id from the server to the client when the file upload is completed and assembled
** therefore if you don't mind in do not use the beauty of the TransferManager you could write "your own TransferMananger" than you will have full control, but again on the client side we don't really want to add custom code but have a standard and simple approach (but that is for my scenario), if you decide to do it manually it can be done I have already tried and works !
So as a alternative we though in send from the server via the eTag, which is not great but will do the job and will keep the client side simple and clean
Any suggestion in how to send this value back in a better way ?
Upload up = tm.upload(bucketName, file.getName(), file);
UploadResult result = (UploadResult) ((UploadImpl) up).getMonitor().getFuture().get();
String uniqueIdFromServer = result.getETag();

How to make client not disconnect when server response takes a long time

I have a Java backend with REST-API and an Angularjs frontend. Users can use the frontend to request information from the backend. When this happens, the backend generates a file on the fly and sends it to the frontend. So far so good.
The problem occurs when users request large amounts of information. This makes generating the file take so long that the frontend times out and aborts the connection.
Is there a way to reassure the client that a response is actually going to come, or increase the timeout limit for this one endpoint only? Alternatively, is there a way for the server to send two responses, one immediately after receiving the request and one after the file is generated?
The API endpoint looks like this:
#Path("download")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
#Consumes(MediaType.APPLICATION_JSON)
public Response download() {
StreamingOutput stream = //stream containing file
return Response.ok(stream)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"download.xlsx\"")
.build();
}
The frontend makes the request by doing window.open(download url, '_blank', '') (the content of the file depends on previous input from the user).

Deserialize Google Web Kit Response (Java) and Java Servlets

I have a monolithic legacy application that I need to read and submit data to. It's using Google Web Kit and Java Servlets.
I have access to the source code, but I'm new to both Servlets and GWT.
I'm trying to encapsulate a rest client in my project that can communicate with GET/POST rest calls to the legacy server.
I've been able to send a POST request using Postman, and then used Reactive Spring 5.0 framework to sending that request.
When I try to deserialize the response, I'm running into a ton of errors.
How would I deserialize this payload?
7|0|7|http://localhost:8080/testproject/
|29F4EA1240F157649C12466F01F46F60|
com.test.client.GreetingService|greetServer|java.lang.String|
myInput1|myInput2|1|2|3|4|2|5|5|6|7|
I've searched all day, and followed a few blogs like these:
https://docs.google.com/document/d/1eG0YocsYYbNAtivkLtcaiEE5IOF5u4LUol8-LL0TIKU/edit#
https://blog.gdssecurity.com/labs/2009/10/8/gwt-rpc-in-a-nutshell.html
I'm not sure code wise how I can serialize them into my own object for my new service.
static WebClient webClient = WebClient.create();
public static void main(String[] args) {
Mono<String> body = Mono.just("7|0|7|http://localhost:8080/testproject/|29F4EA1240F157649C12466F01F46F60|com.test.client.GreetingService|greetServer|java.lang.String|myInput1|myInput2|1|2|3|4|2|5|5|6|7|");
Mono<String> response = webClient.post()
.uri("http://localhost:8080/testproject/")
.header("Content-Type", "text/x-gwt-rpc;charset=UTF-8")
.header("X-GWT-Module-Base", "http://localhost:8080/testproject/")
.header("X-GWT-Permutation", "29F4EA1240F157649C12466F01F46F60")
.cookie("JSESSIONID", "2BCEBF12GE2C3A0335F5012812A73638")
.body(body, String.class)
.retrieve()
.bodyToMono(String.class);
String unBlocked = response.block();
System.out.println(unBlocked);
//OK[1,1,["java.lang.Integer/3438228391"],0,2]
try {
ServerSerializationStreamReader streamReader = new ServerSerializationStreamReader(
Thread.currentThread().getContextClassLoader(), null);
streamReader.prepareToRead(unBlocked);
System.out.println(streamReader.readObject());
} catch ( Exception e) {
e.printStackTrace();
}
}
Error:
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: This application is out of date, please click the refresh button on your browser. ( Malformed or old RPC message received - expecting version between 5 and 7 )
I've tried every version of GWT because of the malformed RCP message.
Also, I tried to stick it into a string, which I'm sure is failing on its own.
You are trying to decode the server response with the code meant decode the client request. At present they use a different format for historical reasons - note how the response starts with "//OK", but the request has the version/flags/stringcount "7|0|7" beginning.
In at least a small part this is because when a client calls a server, it needs to describe what version it is speaking and where the server should find the file listing the set of classes that the client expects are allowed to be serialized. When the server responds, since the client already told it about the typed that can be serialized, it doesn't need to tell the client the same thing again.
Reading the com.google.gwt.user.client.rpc.impl.ClientSerializationStreamReader class and its docs will show the response format and how it can be decoded into objects. There is presently no server-side code that I'm aware of that is intended to do this job, but could probably be written with fairly little difficulty, just some persistence.

Decode HTTPS request payload on server using jNetPcap

Before jumping into the problem I would like to share that what is the structure of my network. I have 3 computers where 1 is acting as a server and rest of the machines are acting as clients. Server is connected to internet and sharing it with other two machines.
I have been trying to log all the HTTPS request on my server by using Jnetpcap library. I have logged all the requests from my HTTP very easily. But, unable to get grip on HTTPS requests.
My PacketHandler snippet is :
PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {
public void nextPacket(PcapPacket packet, String user) {
System.out.printf("Received packet at %s caplen=%-4d len=%-4d %s\n",
new Date(packet.getCaptureHeader().timestampInMillis()),
packet.getCaptureHeader().caplen(), // Length actually captured
packet.getCaptureHeader().wirelen(), // Original length
user // User supplied object
);
}
};
In response it returns
youtube.com.https ......Blah Blah
But, didn't return the youtube video ID that I was willing to capture.
It's the "S" in "HTTPS" that's the problem.
HTTP requests and replies are plain text. HTTPS is HTTP-over-{SSL,TLS}, and the plain text being sent in those requests and replies is almost always encrypted. You'd have to decrypt it, which is Not Easy - Wireshark has code that can sometimes do it, if you provide the right information, but, as the Wireshark Wiki entry for SSL indicates, and as a look at the Wireshark code to do the decryption will show, there's a significant amount of work involved.

How to send text and binary data from a custom netty HTTP server in Java?

Based on netty 3.6 I am implementing a small HTTP server into my Java desktop application. By now I have successfully created the basic HTTP server layout, I can send various text-based files to my browser-based clients.
In my netty server pipeline factory I create new channel pipelines as following:
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("handler", new HttpServerHandler());
In my HttpServerHandler class I send text data to the clients as following:
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setHeader(CONTENT_TYPE, contentType + "; charset=UTF-8");
response.setHeader(PRAGMA, "no-cache");
response.setContent(ChannelBuffers.copiedBuffer(responseText, CharsetUtil.UTF_8));
if(keepAlive)
{
response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
}
ChannelFuture future = e.getChannel().write(response);
Good. Now I additionally want to send binary data (e.g. images) to my clients. Since I found no online example on how to achieve this I have two questions:
How do I need to modify the channel pipeline to be able to send both, text and binary data to my clients?
How to modify the HttpServerHandler class in order to send a binary file to the client?
I do not think there is any more differenece between context or binary. I think what you need to do is set the content-type right. Then browser know how to handle it.
If you want to send a png file to browser, set the content-type to "image/png".

Categories