GWT displaying image specified from servlet - gwt

I use a servlet to access a folder outside the web container to load some graphics to web application by using GWT. I use the following snippet in servlet to test the idea:
String s = null;
File inputFile = new File("C:\\Documents and Settings\\User\\My Documents\\My Pictures\\megan-fox.jpg");
FileInputStream fin = null;
try {
fin = new FileInputStream(inputFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte c[] = new byte[(int) inputFile.length()];
try {
fin.read(c);
} catch (IOException e) {
e.printStackTrace();
}
try {
fin.close();
} catch (IOException e1) {
e1.printStackTrace();
}
String imgFolderPath = getServletContext().getRealPath("/")+"img";
File imgFolder = new File(imgFolderPath);
imgFolder.mkdir();
File newImage = new File("megan-fox.jpg");
FileOutputStream fout = null;
try {
fout = new FileOutputStream(newImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fout.write(c);
} catch (IOException e) {
e.printStackTrace();
}
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
boolean success = newImage.renameTo(new File(imgFolderPath, newImage.getName()));
The code in servlet reads the image file from the specified folder in hard disk, creates a new folder called 'img' in war folder and copies to it the jpg file. Then it returns to the client the path to the image (for now hardcoded as) '/img/megan-fox.jpg'.
The client then uses the Image class in GWT with the returned path-string to display the image, like in the following snippet:
public void onSuccess(String result) {
String myImage = result;
image = new Image(myImage);
RootPanel.get().add(image);
closeButton.setFocus(true);
}
I need to know if there is a way to achieve the same result without using the 'intermediate' step of creating a folder in the web container root (optional) and copying the file there in order to access it with Image GWT class and display it?
updated: The original servlet class.
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
// This method is called by the servlet container to process a GET request.
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Get the absolute path of the image
ServletContext sc = getServletContext();
// i want to load the image in the specified folder (outside the web container)
String filename = sc.getRealPath("C:\\Documents and Settings\\User\\My Documents\\My Pictures\\megan-fox.jpg");
// Get the MIME type of the image
String mimeType = sc.getMimeType(filename);
if (mimeType == null) {
sc.log("Could not get MIME type of "+filename);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
// Set content type
resp.setContentType(mimeType);
// Set content size
File file = new File(filename);
resp.setContentLength((int)file.length());
// Open the file and output streams
FileInputStream in = new FileInputStream(file);
OutputStream out = resp.getOutputStream();
// Copy the contents of the file to the output stream
byte[] buf = new byte[1024];
int count = 0;
while ((count = in.read(buf)) >= 0) {
out.write(buf, 0, count);
}
in.close();
out.close();
}
// This is the method that is called from the client using GWT-RPC
public String greetServer(String input) throws IllegalArgumentException {
HttpServletRequest req = this.getThreadLocalRequest();
HttpServletResponse res = this.getThreadLocalResponse();
try {
doGet(req, res);
} catch (IOException e) {
e.printStackTrace();
}
// actually i dont know what that means but i thought i would have to returned something like the image's url?
return res.encodeURL("/img/image0.png");
}
}
I logically misused the method that was proposed to solve my problem. What is the correct way?

Sure, just have your servlet serve the image directly:
Set the Content-Type header to image/jpeg.
Write out image file contents to servlet response writer.
Here is an example.

Related

How to choose the encode of a file created by SmbFileOutputStream?

I am using a method to create a file in a specific path in a shared folder inside my local net.
public static void stringToArquivoTextoRemoto(String path, String fileName, String content, NtlmPasswordAuthentication auth) {
String absolutePath = path + File.separator + fileName;
try {
jcifs.Config.setProperty("jcifs.smb.client.disablePlainTextPasswords", "false");
SmbFile smbFile = new SmbFile(absolutePath, auth);
SmbFileOutputStream smbFileOutputStream = new SmbFileOutputStream(smbFile);
smbFileOutputStream.write(content.getBytes());
smbFileOutputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (SmbException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Now, I am trying to change the encode from "UTF-8" to "ISO-8859-1".
I already tried to put:
jcifs.Config.setProperty( "jcifs.encoding", "ISO-8859-1" );
But it didn't work.
I found a lot of information about how to change the encode using the FileOutputStream, but I found nothing about this using SmbFileOutputStream.
What do I need to do to choose the encode of a file created by SmbFileOutputStream?
This will solve the issue:
package fileWriting;
import java.io.IOException;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;
public class testWriting {
public static void main(String[] args) throws IOException {
String user = "domain;username:password";
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(user);
String path = "smb://shared/Projects/test.txt";
SmbFile sFile = new SmbFile(path, auth);
try (SmbFileOutputStream sfos = new SmbFileOutputStream(sFile)) {
String v = "Test for file writing!";
byte[] utf = v.getBytes("UTF-8");
byte[] latin1 = new String(utf, "UTF-8").getBytes("ISO-8859-1");
sfos.write(latin1,0,latin1.length );
}
}
}

Uploading file whose name is in unicode

I have some JavaScript code that upload file to server using ajax and form data and server side java code that accept it. I can upload English file name. But when I uploaded other Unicode file name, the file name I got in server side is unreadable. The following is code snippet.
JavaScript
var f = new FormData();
f.append("file", file);
xhr.send(f);
Java
public void upload(MultipartFormDataInput input) {
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
List<InputPart> inputParts = uploadForm.get("user_file[]");
IFileInfo file = null;
for (InputPart inputPart : inputParts) {
try {
MultivaluedMap<String, String> header = inputPart.getHeaders();
fileName = getFileName(header);
System.out.println("File name is " + fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String getFileName(MultivaluedMap<String, String> header) {
System.out.println("Headers is " + header.getFirst("Content-Disposition"));
String[] contentDisposition = header.getFirst("Content-Disposition")
.split(";");
for (String filename : contentDisposition) {
if ((filename.trim().startsWith("filename"))) {
String[] name = filename.split("=");
String finalFileName = name[1].trim().replaceAll("\"", "");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return finalFileName;
}
}
return "unknown";
}
When I upload "大家好.jpg" , I got server side log showing the following.
Headers is form-data; name="user_file[]"; filename="���������.jpg"
File name is ���������.jpg
I think browser encode file name before uploading it.But I don't know which encoding did it used or how to decode it back. Any help is much appreciated.

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

How can I marshal Objects from a Socket without closing it? (JAXB Marshaling from Inputstream via Socket)

I have tried in many different ways to send my xml document over a socket connection between a server and a client without closing the socket after sending (keep the outputstream open, for sending another document). I have found several sites who claimed that it should work, so I tried it in all the ways they sugested, but I did not found a way which works.
(that describes the same what I would like to do: http://jaxb.java.net/guide/Designing_a_client_server_protocol_in_XML.html)
The follwing code works perfectly if I am closing the socket after sending (#code marsh.marshal(element, xsw);), but it stucks on unmarshaling on the server side, if I try to keep the socket open.
Client Side....
public void sendMessage(String message){
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library");
Marshaller marsh = jaxbContext.createMarshaller();
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marsh.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.org/WizardShema WizardsSchema.xsd");
ObjectFactory of = new ObjectFactory();
// the Dataset is the root element of the xml document
Dataset set = new Dataset("CONN01", "CONTR", "MCL01#localhost", "SV01#localhost:32000");
CommandSet cmdSet = new CommandSet();
Command cmd = new Command();
cmd.setFunctionName("RegisterAs");
Param p = new Param();
p.setString("RemoteClient");
cmd.addParameter(p);
cmdSet.addCommand(cmd);
set.setInstruction(cmdSet);
// creates a valid xml dataset, with startDocument, startElement...
JAXBElement<Dataset> element = of.createData(set);
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(mOOS);
marsh.marshal(element, xsw);
xsw.flush();
} catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
SERVER Side....
private void handleMessage() {
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library") ;
Unmarshaller um = jaxbContext.createUnmarshaller();
XMLInputFactory xmlif = XMLInputFactory.newInstance();
// XMLEventReader xmlr = xmlif.createXMLEventReader(mOIS);
XMLStreamReader xmlr = xmlif.createXMLStreamReader(mOIS, "UTF8");
// move to the root element and check its name.
xmlr.nextTag();
System.out.println("TagName:" + xmlr.getLocalName());
xmlr.require(START_ELEMENT, null, "Data");
JAXBElement<Dataset> obj = um.unmarshal(xmlr, Dataset.class);
Dataset set = obj.getValue();
System.out.println("ID:"+ set.getID());
} catch (JAXBException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}

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.