get values from server to applet [duplicate] - java

I have an applet and I must send a request to a web application to get data from the server that is in a database. I am working with objects and it is very useful that the server responses me with objects!!
How an applet can communicate with a server?
I think web services method, RMI and... make me happy, but which is the best and reliable?

As long as its only your applet communicating with the server you can use a serialized object. You just need to maintain the same version of the object class in both the applet jar and on the server. Its not the most open or expandable way to go but it is quick as far as development time and pretty solid.
Here is an example.
Instantiate the connection to the servlet
URL servletURL = new URL("<URL To your Servlet>");
URLConnection servletConnect = servletURL.openConnection();
servletConnect.setDoOutput(true); // to allow us to write to the URL
servletConnect.setUseCaches(false); // Write the message to the servlet and not from the browser's cache
servletConnect.setRequestProperty("Content-Type","application/x-java-serialized-object");
Get the output stream and write your object
MyCustomObject myObject = new MyCustomObject()
ObjectOutputStream outputToServlet;
outputToServlet = new ObjectOutputStream(servletConnection.getOutputStream());
outputToServlet.writeObject(myObject);
outputToServlet.flush(); //Cleanup
outputToServlet.close();
Now read in the response
ObjectInputStream in = new ObjectInputStream(servletConnection.getInputStream());
MyRespObject myrespObj;
try
{
myrespObj= (MyRespObject) in.readObject();
} catch (ClassNotFoundException e1)
{
e1.printStackTrace();
}
in.close();
In your servlet
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
MyRespObject myrespObj= processSomething(request);
response.reset();
response.setHeader("Content-Type", "application/x-java-serialized-object");
ObjectOutputStream outputToApplet;
outputToApplet = new ObjectOutputStream(response.getOutputStream());
outputToApplet.writeObject(myrespObj);
outputToApplet.flush();
outputToApplet.close();
}
private MyRespObject processSomething(HttpServletRequest request)
{
ObjectInputStream inputFromApplet = new ObjectInputStream(request.getInputStream());
MyCustomObject myObject = (MyCustomObject) inputFromApplet.readObject();
//Do Something with the object you just passed
MyRespObject myrespObj= new MyRespObject();
return myrespObj;
}
Just remember that both Objects that you are passing need to implement serializable
public Class MyCustomObject implements java.io.Serializable
{

Related

Restlet & MULTIPART_FORM_DATA or another way to put files on Google App Engine via Restlet

I tried to receive files via restlet but only gets the complete MULTIPART_FORM_DATA.
How can I extract my specific file?
I found some code-blocks but the types of them are not available...
RESTlet: How to process multipart/form-data requests?
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1000240);
// 2/ Create a new file upload handler
RestletFileUpload upload = new RestletFileUpload(factory);
My current code:
#Put
public void handleUpload(Representation entity) {
if (entity !=null) {
if (MediaType.MULTIPART_FORM_DATA.equals(entity.getMediaType(), true)) {
Request restletRequest = getRequest();
Response restletResponse = getResponse();
HttpServletRequest servletRequest = ServletUtils.getRequest(restletRequest);
HttpServletResponse servletResponse = ServletUtils.getResponse(restletResponse);
try {
Upload2(restletRequest, entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public void Upload2(Request req, Representation entity) throws IOException
{
...
GcsOutputChannel outputChannel = gcsService.createOrReplace(fileName, GcsFileOptions.getDefaultInstance());
ObjectOutputStream oout = new ObjectOutputStream(Channels.newOutputStream(outputChannel));
copy(entity.getStream(), oout);
oout.close();
After storing with this method I have something like that and I only want to store the content with the name "picture":
��z------WebKitFormBoundarysOvzWKPqyqW7DiTu
Content-Disposition: form-data; name="picture"; filename="_MG_4369.jpg"
Content-Type: image/jpeg
����*ExifII*
As far as I read parsing of multipart form data isn’t supported yet? But there must be a solution to send files via restlet
I tried the rest-calls via postman for chrome. The is only on multiparts the support for files. Is a possible solution to send the image as a raw-text?
You will need to add Exception handling and deal with the InputStream and potentially clean up of temp files (see DiskFileItemFactory docs) but the basics are as follows, when using the org.restlet.ext.fileupload library.
#Put
public void handleUpload(Representation entity) {
List<FileItem> items = new RestletFileUpload(new DiskFileItemFactory())
.parseRepresentation(representation);
for (FileItem item : items) {
if (!item.isFormField()) {
MediaType type = MediaType.valueOf(item.getContentType());
InputStream inputStream = item.getInputStream();
}
}
}
for a gae Solution try replacing the DiskFileItemFactory with a gwtupload.server.MemoryFileItemFactory.
You should send your file uploads as an InputStream. Then you can use this:
#Put
public void handleUpload(InputStream entity) {
}
The file is now its stream and will no longer have form data inside of it. To send a file as a stream, you can set up a client in java (using jersey, for example).
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
File f = new File("C:/file/to/upload.zip");
InputStream data = new FileInputStream(f);
Client client = Client.create();
client.setChunkedEncodingSize(1024);
WebResource resource = client.resource("http://localhost:80/your/uri");
ClientResponse response = resource.accept("application/x-octet-stream").type("application/x-octet-stream").post(ClientResponse.class, data);
Now that you have data, you can set up a client to post data to your server. I was trying this using multipart form data and postman before. I went mad trying to get multipart data to work. But this is the solution I have been using instead. And it works perfectly.

Servlet that gets file from a url and sends it to users

So I'm relatively new to Javax Servlet and I"m supposed to modify some code at work. As requested by the company, I can't post my code up here. So basically I have a server set up on a cloud service and I deployed my app on that server. When I run my app, the users can type in :8080/appname/resources/filename. In the code, the filename will take me to the correct url of the file located on a CDN network. How can I play it back to the user through the servlet? Because it doesn't directly reside on my server but it's being directed somewhere else. I'll try to write a simple example to explain what I mean
procesRequest(HttpServletRequest request, HttpServletResponse reponse){
String requestFile = request.getPathInfo();
File file = new File(basePath,URLDecoder.decode(requestedFile, "UTF-8"));
RandomAccessFile input = new RandomAccessFile(file, "r");
OutputStream output = response.getOutputStream();
playBack(input, output);
}
playBack(RandomAccessFile input, OutputStream output){
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read;
while ((read = input.read(buffer))>0)
{
output.write(buffer, 0, read);
}
}
So in the above example, the file will reside on the server itself. And the basePath refers to the folder on the server where all the files are stored. So it can just playback the file. However, I want to modify it so that instead of getting a file on the server, it will get a file from a url and play it back. Right now I just have the URL hardcode in for testing purpose.
Make a request to that server and just give back the response you get from that server.
Provided you have a webapp running at that server which accepts your requests, locate the file and give back the response to you.
Without more details to go on, the conceptual solution is to open an input stream (file/data?) and read the contents while writing the same bytes read to the Servlet's output stream.
You can use a URLConnection for serves the real file. The following may inspire and help a little. You need to know what to replace on the request path (in the method convertToRemoteUrl).
#WebServlet(urlPatterns = { "/resources/*" })
public class ResourceServlet extends HttpServlet {
public static void copy(InputStream in, OutputStream out)
throws IOException {
final byte[] buffer = new byte[1024];
for (int length; (length = in.read(buffer)) != -1;) {
out.write(buffer, 0, length);
}
out.flush();
out.close();
in.close();
}
public static URL convertToRemoteUrl(final HttpServletRequest request)
throws MalformedURLException {
URL url = request.getRequestURL();
StringBuilder sb = new StringBuilder(256);
sb.append("http://realdomain.com");
sb.append(url.getPath().replace(
request.getContextPath(), "/realappname"));
return new URL(sb.toString());
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
final URL url = convertToRemoteUrl(request);
final URLConnection connection = url.openConnection();
response.setContentType(connection.getContentType());
copy(connection.getInputStream(), response.getOutputStream());
}
}
e.g. The request URL can be converted from:
http://domain.com:8080/appname/resources/example.txt
to
http://realdomain.com:8080/realappname/resources/example.txt

Reading object in client side written in the HttpServletResponse

I am uploading a file through a com.google.gwt.user.client.ui.FileUpload, when the file arrives to the server I want to be able to tell the client what is the status of the upload. To this end I wrote a simple Message class that implements the java.io.Serializable interface and I write the object to the response this way:
outputStream = new ObjectOutputStream(response.getOutputStream());
outputStream.writeObject(object);
outputStream.flush();
outputStream.close();
The problem is that in the client I don't know how to deserialize this object. how can I access the outputstream to reconstruct the object, I have this method:
form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler()
{
public void onSubmitComplete(SubmitCompleteEvent event)
{
String result = event.getResults();
});
}
I know I can just write a simple String into the response and set the content type to "text/plain", but I would really like to know to do it with objects. Any help would be appreciated.

how to clear contents of a PrintWriter after writing

Good evening, i want to know how to clear the data written to a PrintWriter, i.e. is it possible to remove the data from a PrintWriter after printing?
here in this servlet i print some text to the response and at the line denoted by # i want to remove all the previously printed data and print new stuff:
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String uName = request.getParameter("uName");
String uPassword = request.getParameter("uPassword");
if (uName .equals("Islam")) {
out.println("Valid-Name");
if (uPassword !=null) {
if (uPassword .equals("Islam")) {
// # clear the writer from any printed data here
out.println("Valid-password");
} else {
out.println("");
out.println("InValid-password");
}
}
} else {
out.println("InValid-Name");
}
}
Note: i tried out.flush() but the old printed text remains
Create an in-memory PrintWriter using a StringWriter. You can get the underlying buffer from the StringWriter and clear it if you need to.
StringWriter sr = new StringWriter();
PrintWriter w = new PrintWriter(sr);
w.print("Some stuff");
// Flush writer to ensure that it's not buffering anything
w.flush();
// clear stringwriter
sr.getBuffer().setLength(0);
w.print("New stuff");
// write to Servlet out
w.flush();
response.getWriter().print(sr.toString());
HttpServlteResponse.resetBuffer() will clear the buffered content. But yes, if the response is already flushed to the client it will throw IllegalStateException. Because it is illegal to clear after partial response is sent to the client.
resetBuffer........
void resetBuffer()
Clears the content of the underlying buffer in the response without clearing headers or status code. If the response has been committed, this method throws an IllegalStateException.
References:
Cause of Servlet's 'Response Already Committed'
You can't do that with the original PrintWriter you get from the response, as that's backed by the actual OutputStream corresponding to the client connection. What you write there goes right to the browser via the wire (after some buffering), so you can't "take it back".
What you can do is write your message in some StringBuilder and once you know it's good to go, write it to the PrintWriter.
If you want this logic to be applied in multiple places (transparently), you can consider writing a filter that wraps the original response in an HttpServletResponseWrapper which returns a "fake" OutputStream or PrintWriter and performs this check prior to actually sending it over the wire.
public class CensorshipFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
CensorshipResponseWrapper wrapper = new CensorshipResponseWrapper(httpServletResponse);
chain.doFilter(request, wrapper);
String output = wrapper.sw.toString();
if ( output.contains("Some forbidden pattern") ) { // your check goes here
// throw exception or whatever
} else { // write the whole thing
httpServletResponse.getWriter().write(output);
}
}
#Override
public void destroy() {
}
static class CensorshipResponseWrapper extends HttpServletResponseWrapper {
private final StringWriter sw = new StringWriter();
public CensorshipResponseWrapper(HttpServletResponse response) {
super(response);
}
#Override
public ServletOutputStream getOutputStream() throws IOException {
// you may also fake the output stream, if some of your servlets use this method
return super.getOutputStream();
}
#Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(sw);
}
}
}
What ended up working for me was to change the logic of how I was outputting my data.
This is the data structure I was outputting that stored the results of a search using the text from a html form as input.
private final TreeMap<String, ArrayList<SearchResult>> searchResults;
So I was iterating over the contents of this data structure and printing it out to html.
public void writeSearchResultsToHtml(PrintWriter writer)
{
try
{
JSONTreeWriter. writeSearchResultsToHtml(searchResults, writer);
} catch (ArithmeticException | IllegalArgumentException | IOException | NoSuchElementException e)
{
System.err.println("Unable to write the search results builder to JSON to the file html.");
}
// clear results for next search otherwise
// the next search will contain the previous
// results, store them in history.
searchResults.clear();
}
Clearing the data structure worked great given my servlet setup.
Here was my main serverlet loop logic:
public void startServer()
{
// seed the database for testing
crawler.startCrawl("http://cs.usfca.edu/~cs212/birds/birds.html");
index.toJSON("index.json");
// type of handler that supports sessions
ServletContextHandler servletContext = null;
// turn on sessions and set context
servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContext.setContextPath("/");
servletContext.addServlet(ViewServlet.class, "/");
// default handler for favicon.ico requests
DefaultHandler defaultHandler = new DefaultHandler();
defaultHandler.setServeIcon(true);
ContextHandler defaultContext = new ContextHandler("/favicon.ico");
defaultContext.setHandler(defaultHandler);
// setup handler order
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{defaultContext, servletContext});
openWebBrowser();
// setup jetty server
Server server = new Server(portNumber);
server.setHandler(handlers);
try
{
server.start();
server.join();
} catch (Exception e)
{
e.printStackTrace();
}
}

Why download popup window in browser not showing up when using JAX-RS v.s. standard servlet?

When I try using standard servlet approach, in my browser the popup window shows up asking me whether to open .xls file or save it.
I tried the exactly same code via JAX-RS and the browser popup won't show up somehow. Has anyone encounter this?
JAX-RS way that won't display popup:
#Path("excellaTest")
public class ExcellaTestResource {
#Context
private UriInfo context;
#Context
private HttpServletResponse response;
#Context
private HttpServletRequest request;
public ExcellaTestResource() {
}
#Path("horizontalProcess")
#GET
//#Produces("application/vnd.ms-excel")
#Produces("application/vnd.ms-excel")
public void getProcessHorizontally() {
try {
URL templateFileUrl = this.getClass().getResource("myExcelTemplate.xls");
String templateFilePath = URLDecoder.decode(templateFileUrl.getPath(), "UTF-8");
String outputFileDir = "MasatoExcelHorizontalOutput";
ReportProcessor reportProcessor = new ReportProcessor();
ReportBook outputBook = new ReportBook(templateFilePath, outputFileDir, ExcelExporter.FORMAT_TYPE);
ReportSheet outputSheet = new ReportSheet("myExcelSheet");
outputBook.addReportSheet(outputSheet);
reportProcessor.addReportBookExporter(new OutputStreamExporter(response));
reportProcessor.process(outputBook);
System.out.println("done!!");
}
catch(Exception e) {
System.out.println(e);
}
return;
}
}//end class
class OutputStreamExporter extends ReportBookExporter {
private HttpServletResponse response;
public OutputStreamExporter(HttpServletResponse response) {
this.response = response;
}
//ReportProcessor output()
//This method is call when ReportProcessor process() is invoked.
//The Workbook from POI API can be used to write to stream
#Override
public void output(Workbook book, BookData bookdata, ConvertConfiguration configuration) throws ExportException {
//TODO write to stream
try {
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=masatoExample.xls");
book.write(response.getOutputStream());
response.getOutputStream().close();
System.out.println("booya!!");
}
catch(Exception e) {
System.out.println(e);
}
}
}//end class
What JAX-RS framework are you using?
My guess is that your code doesn't work, because you are returning void. The framework you are using probably recognizes void as HTTP 204 No Content. This causes browser to skip the actual response body and to ignore conntent-disposition header.
As I already wrote you in a parallel thread: try to returning Response object. You can put either OutputStream or byte[] as entity as set the content-disposition header.
I have never used class level injection for a jax-rs service. I suggest one of 2 solutions.
1) Try injecting the request and response as method arguments.
2) Output your file to a byte array output stream and return a byte array from your method instead of void.

Categories

Resources