Can a RESTfull service method send any Object to the client? - java

I have a restfull service , in that service i should send one inputstream object to the client. So i wrote the following code...in service method..
#GET
#Path("/getFile")
#Produces("application/pdf")
public InputStream getFile() throws Exception {
FileInputStream fin = null;
FileOutputStream fout = null;
DataInputStream dis = null;
System.out.println("getFile called in server...");
File serverFile = null;
System.out.println("getfile called..");
try {
serverFile = new File("E:\\Sample2.txt");
fin = new FileInputStream(serverFile);
dis = new DataInputStream(fin);
fin.close();
// dis.close();
} catch (Exception e) {
System.out.println("Exception in server appl..***************");
e.printStackTrace();
}
return dis;
}
In my client application im calling this service as...
String clientURL = "http://xxxxxxx:xxxx/RestfullApp02/resources/LoadFile";
Client client = Client.create();
WebResource webResource = client.resource(clientURL);
InputStream ob = webResource.path("getFile").get(InputStream.class);
But i unable to get the response , it sending 500 error.. like below errror....
com.sun.jersey.api.client.UniformInterfaceException: GET http://myIp:myport/RestfullApp02/resources/LoadFile/getFile returned a response status of 500
Help Me

Please refer the below link, I feel you can solve the issue by it.
http://wpcertification.blogspot.in/2011/11/returning-binary-file-from-rest-service.html

Related

Java: Implementing a Multithreaded web server

Trying to work on this assignment for practice. Got stuck few with two issues.
Where should I stop the Thread after printing the request on console? Later I would need to do that after sending the response.
From where should I send the response back? I can easily do it from processRequest(). Was thinking if there is anyway to send a HttpResponse back.
Would it be ok to send the response back from HttpRequest class itself?
Code
Main class
public final class WebServer {
public static void main(String[] args) throws Exception {
int port = 1983;
final ServerSocket server = new ServerSocket(port);
System.out.println("Comes here");
Socket client = null;
while (true) {
client = server.accept();
System.out.println("Got the connection" + client.toString());
final HttpRequest request = new HttpRequest(client);
Thread thread = new Thread(request);
thread.start();
}
}
}
HttpRequest.java
final class HttpRequest implements Runnable {
Socket socket;
public HttpRequest(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
processRequest();
} catch (IOException e) {
e.printStackTrace();
}
}
private void processRequest() throws IOException {
String headerline = null;
DataOutputStream out = null;
BufferedReader in = null;
out = new DataOutputStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((headerline = in.readLine()).length() != 0) {
System.out.println(headerline);
}
out.close();
in.close();
socket.close();
}
}
The thread will terminate as soon as the socket is closed.
To output to the client, in this form, you must generate your own Http header that needs to be sent to the client plus all of your data that you're sending to your client. To do this, you can do:
out.writeBytes(<HttpHeaderString>);
Then for your file, you can do something like this:
FileInputStream fileToClient;
OutputStream toClient;
byte[] buffer = new byte[2048];
int bytes = 0;
while ((bytes = fileToClient.read(buffer)) != -1){
toClient.write(buffer, 0, bytes);
}
The page mentions instance of Thread class, but ideally, you don't stop threads, you return them back to the pool. Such that you don't create a new thread for every request but reuse threads.
pool = Executors.newFixedThreadPool(poolSize);
while (true) {
pool.execute(new HttpRequest(client);
}
You can do it from anywhere just keep reference to Socket's OutputStream and don't forget to flush it.
As for the naming, it's bit awkward to send response back from request object. Just rename your HttpRequest to something like HttpRequestHandler, which assumes that you'll handle incoming request here the way you prefer, and it should be fine.

Jersey client to download and save file

I Am new to jersey/JAX-RS implementation.
Please find below my jersey client code to download file:
Client client = Client.create();
WebResource wr = client.resource("http://localhost:7070/upload-0.0.1-SNAPSHOT/rest/files/download");
Builder wb=wr.accept("application/json,application/pdf,text/plain,image/jpeg,application/xml,application/vnd.ms-excel");
ClientResponse clientResponse= wr.get(ClientResponse.class);
System.out.println(clientResponse.getStatus());
File res= clientResponse.getEntity(File.class);
File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");
res.renameTo(downloadfile);
FileWriter fr = new FileWriter(res);
fr.flush();
My Server side code is :
#Path("/download")
#GET
#Produces({"application/pdf","text/plain","image/jpeg","application/xml","application/vnd.ms-excel"})
public Response getFile()
{
File download = new File("C://Data/Test/downloaded/empty.pdf");
ResponseBuilder response = Response.ok((Object)download);
response.header("Content-Disposition", "attachment; filename=empty.pdf");
return response.build();
}
In my client code i am getting response as 200 OK,but i am unable to save my file on hard disk
In the below line i am mentioning the path and location where the files need to be saved.
Not sure whats going wrong here,any help would be appreciated.Thanks in advance!!
File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");
For folks still looking for a solution, here is the complete code on how to save jaxrs response to a File.
public void downloadClient(){
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:7070/upload-0.0.1-SNAPSHOT/rest/files/download");
Response resp = target
.request("application/pdf,image/jpeg,application/xml,application/vnd.ms-excel")
.get();
if(resp.getStatus() == Response.Status.OK.getStatusCode())
{
InputStream is = resp.readEntity(InputStream.class);
fetchFeed(is);
//fetchFeedAnotherWay(is) //use for Java 7
IOUtils.closeQuietly(is);
System.out.println("the file details after call:"+downloadfile.getAbsolutePath()+", size is "+downloadfile.length());
}
else{
throw new WebApplicationException("Http Call failed. response code is"+resp.getStatus()+". Error reported is"+resp.getStatusInfo());
}
}
/**
* Store contents of file from response to local disk using java 7
* java.nio.file.Files
*/
private void fetchFeed(InputStream is){
File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");
byte[] byteArray = IOUtils.toByteArray(is);
FileOutputStream fos = new FileOutputStream(downloadfile);
fos.write(byteArray);
fos.flush();
fos.close();
}
/**
* Alternate way to Store contents of file from response to local disk using
* java 7, java.nio.file.Files
*/
private void fetchFeedAnotherWay(InputStream is){
File downloadfile = new File("C://Data/test/downloaded/testnew.pdf");
Files.copy(is, downloadfile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
I don't know if Jersey let's you simply respond with a file like you have here:
File download = new File("C://Data/Test/downloaded/empty.pdf");
ResponseBuilder response = Response.ok((Object)download);
You can certainly use a StreamingOutput response to send the file from the server, like this:
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream os) throws IOException,
WebApplicationException {
Writer writer = new BufferedWriter(new OutputStreamWriter(os));
//#TODO read the file here and write to the writer
writer.flush();
}
};
return Response.ok(stream).build();
and your client would expect to read a stream and put it in a file:
InputStream in = response.getEntityInputStream();
if (in != null) {
File f = new File("C://Data/test/downloaded/testnew.pdf");
//#TODO copy the in stream to the file f
System.out.println("Result size:" + f.length() + " written to " + f.getPath());
}
This sample code below may help you.
https://stackoverflow.com/a/32253028/15789
This is a JAX RS rest service, and test client. It reads bytes from a file and uploads the bytes to the REST service. The REST service zips the bytes and sends it back as bytes to the client. The client reads the bytes and saves the zipped file.
I had posted this as a response to another thread.
Here's another way of doing it using Files.copy().
private long downloadReport(String url){
long bytesCopied = 0;
Path out = Paths.get(this.fileInfo.getLocalPath());
try {
WebTarget webTarget = restClient.getClient().target(url);
Invocation.Builder invocationBuilder = webTarget.request(MediaType.TEXT_PLAIN_TYPE);
Response response = invocationBuilder.get();
if (response.getStatus() != 200) {
System.out.println("HTTP status " response.getStatus());
return bytesCopied;
}
InputStream in = response.readEntity( InputStream.class );
bytesCopied = Files.copy(in, out, REPLACE_EXISTING);
in.close();
} catch( IOException e ){
System.out.println(e.getMessage());
}
return bytesCopied;
}

Issue getting the images with sockets

I'm writing a proxy server using sockets, now it seems that it's "working" more or less but the problem I'm experiencing now is that the images of the URL's are not getting back to the browser, only the text is returned...
This is the code:
//create inputstream to receive the web page from the host
BufferedInputStream inn = new BufferedInputStream(clientURLSocket.getInputStream());
//create outputstream to send the web page to the client
BufferedOutputStream outt = new BufferedOutputStream(clientSocket.getOutputStream());
URL u = new URL("http://"+url);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
byte[] chunk = new byte[1024];
int bytesRead;
InputStream stream = u.openStream();
while ((bytesRead = stream.read(chunk)) > 0) {
outputStream.write(chunk, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
outt.write(outputStream.toByteArray());
outt.flush();
Maybe ByteArrayOutputStream is not good to receive images?
Edit (sorry for the late response):
This is my new code:
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class Server {
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
#SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket clientSocket = serverSocket.accept();
Socket clientURLSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
clientProcessingPool.submit(new ClientTask(clientURLSocket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private Socket clientSocket;
private Socket clientURLSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
this.clientURLSocket = clientSocket;
}
#Override
public void run() {
try {
String url = null;
String curl = null;
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
String buffer;
while ((buffer = in.readLine()) != null) {
//System.out.println(buffer);
if(buffer.contains("GET"))
{
String[] splitText = buffer.split(" ");
curl = splitText[1];
System.out.println(curl);
}
if(buffer.contains("Host"))
{
//parse the host
url = buffer.replace("Host: ", "");
System.out.println(url);
}
if (buffer.isEmpty()) break;
}
//String IP = InetAddress.getByName(url).getHostAddress().toString();
//new socket to send the information over
clientURLSocket = new Socket(url, 80);
//get data from a URL
/* URL host = new URL("http://"+url);
URLConnection urlConnection = host.openConnection();
InputStream input = urlConnection.getInputStream();
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
input.close();*/
//create inputstream to receive the web page from the host
BufferedInputStream inn = new BufferedInputStream(clientURLSocket.getInputStream());
//create outputstream to send the web page to the client
BufferedOutputStream outt = new BufferedOutputStream(clientSocket.getOutputStream());
URL u = new URL(curl);
HttpURLConnection connection = null;
connection = (HttpURLConnection) u.openConnection();
connection.connect();
//ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
byte[] chunk = new byte[1024];
int bytesRead;
InputStream stream = connection.getInputStream();
while ((bytesRead = stream.read(chunk)) > 0) {
//outputStream.write(chunk, 0, bytesRead);
outt.write(chunk, 0, bytesRead);
outt.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
//outt.write(outputStream.toByteArray());
//outt.flush();
outt.close();
inn.close();
clientURLSocket.close();
/*
out.close();
in.close();
clientSocket.close();
*/
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Now the problem is that google.com is working fine (it shows all the images and text), but for example youtube.com is not working fine (it also shows the text and images but the web is not being showed completely and it's disordered).
What I'm missing in this code?
By the way, thanks EJP & JB Nizet for your help!
It seems you don't understand how HTTP and HTML work.
When you go to http://google.com with your browser, a first request is sent to get the HTML page. The server response contains the HTML markup, and only that. Then the browser reads and parses this HTML markup and sees that it contains (for example)
<img src="logo.png"/>
So it sends a new HTTP request to the URL http://google.com/logo.png. The server sends a response containing the bytes of the logo image.
If your code only sends a single request to http://google.com, you'll never get the logo.
An HTTP proxy is a lot simpler than what you're doing here.
You are supposed to connect to the URL named in the CONNECT command. Not parse the GET and HOST headers. Once you've processed the CONNECT command, the rest is just copying bytes back and forth.

JAX-RS - Wink - Correct way to read a file, using Wink Client

Related to this question which is about how to send a binary file to a client. I am doing this, actually my method #Produces("application/zip"), and it works well for the browser client. Now I'm trying to write some automated tests against the rest service, using the Wink client. So my question is not how to send the file to the client, but for how to consume the file, as a java rest client (in this case Apache Wink).
My resource method looks something like the below... Once I have a Wink ClientResponse object, how can I get the file from it so I can work with it?
#GET
#Path("/file")
#Produces("application/zip")
public javax.ws.rs.core.Response getFile() {
filesToZip.put("file.txt", myText);
ResponseBuilder responseBuilder = null;
javax.ws.rs.core.Response response = null;
InputStream in = null;
try {
in = new FileInputStream( createZipFile( filesToZip ) );
responseBuilder = javax.ws.rs.core.Response.ok(in, MediaType.APPLICATION_OCTET_STREAM_TYPE);
response = responseBuilder.header("content-disposition", "inline;filename="file.zip").build();
} catch( FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
return response;
The method that actually creates the zip file looks like this
private String createZipFile( Map<String,String> zipFiles ) {
ZipOutputStream zos = null;
File file = null;
String createdFileCanonicalPath = null;
try {
// create a temp file -- the ZIP Container
file = File.createTempFile("files", ".zip");
zos = new ZipOutputStream( new FileOutputStream(file));
// for each entry in the Map, create an inner zip entry
for (Iterator<Map.Entry<String, String>> it = zipFiles.entrySet().iterator(); it.hasNext();){
Map.Entry<String, String> entry = it.next();
String innerFileName = entry.getKey();
String textContent = entry.getValue();
zos.putNextEntry( new ZipEntry(innerFileName) );
StringBuilder sb = new StringBuilder();
byte[] contentInBytes = sb.append(textContent).toString().getBytes();
zos.write(contentInBytes, 0, contentInBytes.length);
zos.closeEntry();
}
zos.flush();
zos.close();
createdFileCanonicalPath = file.getCanonicalPath();
} catch (SecurityException se) {
se.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (zos != null) {
zos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return createdFileCanonicalPath;
}
You can consume it simply as input stream and use ZipInputStream to unzip it.
Here's example using Apache HTTP Client:
HttpClient httpclient = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
get.addHeader(new BasicHeader("Accept", "application/zip"));
HttpResponse response = httpclient.execute(get);
InputStream is = response.getEntity().getContent();
ZipInputStream zip = new ZipInputStream(is);

Facing null pointer Exception in at RpcMap?

I am trying to read a serialized DTO at server side object from file, i can read it without any exception but after some exception throws when rpc replies to client side
java.lang.NullPointerException
at com.extjs.gxt.ui.client.data.RpcMap.size(RpcMap.java:198)
what is the issue?
i m using GXT 2.2.5.
here is a server side code
public List<ShellCommand> getCommands(String user, String platform)
throws CVSServiceException {
readFromFile();
if(commands.isEmpty())
return null;
else
return commands;
}
private void readFromFile(){
File readFile = new File(DIR, SHELLCOMMAND);
if(readFile.exists()){
try{
InputStream file = new FileInputStream(readFile);
InputStream buffer = new BufferedInputStream( file );
ObjectInput input = new ObjectInputStream ( buffer );
try{
commands = (List<ShellCommand>) input.readObject();
} catch(Exception e){
e.printStackTrace();
} finally{
input.close();
}
} catch(Exception e){
e.printStackTrace();
}
}
i can read and feel my list commands perfactly but then after calling getcommands() from client side it throws this error causes my RPC call to fail?

Categories

Resources