I created a servlet in java that will give me a xml response when called
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml; charset=utf-8"); // Set the servlet's response type to XML.
PrintWriter out = null;
try {
out = response.getWriter();
XMLOutputFactory of = XMLOutputFactory.newInstance();
XMLStreamWriter writer = of.createXMLStreamWriter(out);
writer.writeStartDocument();
writer.writeStartElement("Test");
for(int i = 1; i <= 100; i++) {
writer.writeStartElement("TheNumber");
writer.writeAttribute("number", "" + i);
writer.writeAttribute("value", "" + Math.pow(2, i));
writer.writeEndElement();
}
writer.writeEndElement();
writer.close();
out.close();
} catch (Exception ex) {
}
}
Now I want to get this xml in flex, can someone give me a hint? I tried mx:WebService and mx:HttpService but both of them did not work.
Thanks in advance
Sebastian
Since you've already solved your issue with HttpService, now it's time to graduate to using Flex remoting with their Granite Data Services or BlazeDS, unless you have some major reason you can't. Parsing XML and using XML for data transmission is a no-no, terrible performance, and in general a bad idea if you can avoid it.
http://www.graniteds.org/
http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/
Just a straight URLLoader will work for you as well.
Related
I'm creating a custom framework (something like portal) for numerous JSF 1.x and 2.x applications. For that purpose I created a servlet filter that "enrich" application HTML with framework menu, breadcrumb, logout, etc. In that filter I read app's HTML, modify it and write it to an output stream. So far everything worked great but now I'm having problem with creating a custom error page.
I tried to read a response status code and based on that code, I'm creating output HTML:
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) req;
HttpServletResponse res = (HttpServletResponse) resp;
StringServletResponseWrapper responseWrapper = new StringServletResponseWrapper(res);
// Invoke resource, accumulating output in the wrapper.
chain.doFilter(req, responseWrapper);
String contentType = res.getContentType();
byte[] data;
if (contentType.contains("text/html")) {
String html = null;
int statusCode = res.getStatus();
LOG.debug("status: {}, committed: {}", statusCode, res.isCommitted());
if (statusCode != 200) {
html = "<!DOCTYPE html>\r\n" +
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n" +
"<head>\r\n" +
"<script type=\"text/javascript\" src=\"/path/to/jquery/jquery-1.11.1.min.js\"></script>\r\n" +
"<title>Error</title>\r\n" +
"</head>\r\n" +
"<body>\r\n" +
"<h1>Error</h1>\r\n" +
"</body>\r\n" +
"</html>";
Collection<String> headerNames = res.getHeaderNames();
Map<String, String> headerMap = new HashMap<String, String>();
for (String header : headerNames) {
headerMap.put(header, res.getHeader(header));
}
res.reset();
for (Map.Entry<String,String> entry : headerMap.entrySet()) {
res.setHeader(entry.getKey(), entry.getValue());
}
res.setStatus(statusCode);
response.setContentType("text/html");
} else {
html = responseWrapper.getCaptureAsString();
}
if (ObjectUtils.isNotEmpty(html)) {
// do some modification
String modifiedResponse = doModification(html);
data = modifiedResponse.getBytes("UTF-8");
response.setContentLength(data.length);
response.getOutputStream().write(data); // this line causes error
}
} else {
data = responseWrapper.getCaptureAsBytes();
response.setContentLength(data.length);
response.getOutputStream().write(data);
}
}
This code works without any problem if status code equals 200 (else clause), but when it's not equal to 200 (I triggered 404 error), the following error occures:
com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[Faces Servlet]: java.lang.IllegalStateException: SRVE0209E: Writer already obtained
I don't really understand why does this error appear. The only difference between two cases is HTML content which is valid in both cases. Any help?
Using Websphere Application Server 8.5.5.18.
EDIT: I've tried to call reset() and then set headers and status code again, but that reset() call causes an IllegalStateException - as stated in javadoc, apparently response has already been committed. As far as I understand, flush() method of ServletOutputStream could cause response to be committed, but I'm not calling it anywhere. I've also added some log to see if response really is committed. In both cases (status 200 and 404) response.isCommitted() returns true. Does that mean that response is committed before doFilter is called?
Option 1 - downgrade JAX-RS to 1.1
Once JAX-RS version is changed back to 1.1 the errors in SystemOut.log will not be shown.
Do the following steps:
Change the JAX-RS version to 1.1 using WAS 9 Admin console. See the detailed instructions at
https://www.ibm.com/support/knowledgecenter/SSEQTP_9.0.0/com.ibm.websphere.base.doc/ae/twbs_jaxrs_coexist_adminconsole.html
Option 2 - move chain.doFilter to the end of your doFilter method
chain.doFilter(req, resp);
}
Option 3 - Remove other usages of PrintWriter or OuputStream
Review application to determine if both PrintWriter and OuputStream were obtained. Modify the failing servlet/JSP to only obtain one or the other.
I am trying to compress my response when the request header contains gzip in Accept-Encoding. However, adding following to app.properties only works when controller method is returning an object.
server.compression.enabled=true
server.compression.min-response-size=1
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
I am writing directly to response stream. So, above compression properties don't work.
My method looks like this:
#GetMapping(path = "/something", produces = MediaType.TEXT_PLAIN_VALUE)
public void getSomething(#RequestParam(name = "paramA") String paramA,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
PrintWriter writer = null;
if (request.getHeader("Accept-Encoding").contains("gzip")) {
writer = new PrintWriter(new OutputStreamWriter(new GZIPOutputStream(response.getOutputStream())));
response.addHeader(HttpHeaders.CONTENT_ENCODING, "gzip");
} else {
writer = response.getWriter();
}
final PrintWriter fwriter = writer;
someObjectInstance.getSomething(paramA).forEach(x -> {
fwriter.write(x.toString());
});
fwriter.flush();
}
When I curl the above method, I get an empty file.
I did try to use the GzipFilter by referring to the following link.
http://www.javablog.fr/javaweb-gzip-compression-protocol-http-filter-gzipresponsewrapper-gzipresponsewrapper.html, which works by the way.
However, the filter requires alot of boilerplate code. Is there a way I can make changes in controller method and solve the problem as in the link mentioned above.
Just realised I was not closing the writer.
After adding fwriter.close(); in the end, the problem was solved.
I have created a dynamic web project in eclipse.
It contains a Servlet ResidentApi.java and two java classes:GeoLocationDemo.java and Geolocation.java. I am calling GeoLocationDemo.java from my servlet and getting result in a ResultSet.But i am not getting any value in ResultSet.
When i ran same GeoLocationDemo.java separatly i am getting right results.I don't know servlet is able to call my java class or not but if it is then why i am not getting results.
I am having hard time debugging it.What i am doing is running .war file of this project every time on tomcat server and checking results there.Please suggest a good method to test it on eclipse.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html");
PrintWriter out = response.getWriter();
ResultSet rs = null;
try{
GeoLocationDemo geo = new GeoLocationDemo(); //Here i created a new object
rs = geo.getResults(); //here i called a method of GeoLocation
}catch(Exception e){
// System.out.println(e);
out.write("<head><b You suck</b></head>");
}
out.write("<head><b>Congratulation! connected</b></head>"); //i am getting this output
try{
while(rs.next()){
String s = rs.getString("Details");
out.write("<head><b> "+s+ " </b></head>"); //not able to get this output
}
}catch(Exception e){
// System.out.println(e);
out.write("<head><b>You Built </b></head>");
}
out.close();
}
Don't put everything in a <head> tag! Open a body somewhere. Don't silently swallow any Exception you might be getting. Do remember to close() the ResultSet. Also, you should probably be returning all of your data in a List with a POJO.
out.write("<body>");
out.write("<b>Congratulation! connected</b><br/>");
try {
while (rs.next()) {
String s = rs.getString("Details");
out.write("<b> "+s+ "</b><br/>");
}
} catch (Exception e){
// System.out.println(e);
out.write("<b>" + e.getMessage() + "</b>");
e.printStackTrace(out);
} finally {
try {
out.close();
} catch (Exception ignored) {
}
try {
rs.close();
} catch (Exception ignored) {
}
}
configure remote debugging between your IDE and Tomcat server e.g. take a look on Remote debugging Tomcat with Eclipse
localize the problem - is the problem in GeoLocationDemo or in ResultSet or in output processing
p.s. do not close resources you never open - out.close(); - it is managed by servlet container
So, I am going to connect to a servlet via an iphone and use HTTP. I am actually developing a multiplayer game and would like to know how I can send specific data to the iphone via HTTP get in java (doGet). I am using libcurl on the iphone (cocos2d-x).
Here is how my code is set up:
size_t write_data(void* buffer, size_t size, size_t nmemb, void *data)
{
//do stuff with data
}
//main or some init method
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl)
{
char *data = "hi imma get=yeah";
curl_easy_setopt(curl, CURLOPT_URL, "http://whatever.com");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
CCLOG("WELP BETTER DO SOMETHING ERROR");
}
curl_easy_cleanup(curl);
}
So, what I would like to know is how I can use the response in the doGet method in java to send a string to that write_function defined above? As in, what do I do with response parameter in the doGet method?
For reference here is the doGet method:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
System.out.println("GET METHOD CALLED");
}
So, now what do I do with that response to pass some data to the write_function?
Thanks, for any and all input!!
By using response's Writer, as shown below.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// tell response what format your output is in, we select plain text here
response.setContentType("text/plain;charset=UTF-8");
// ask the response object for a Writer object
PrintWriter out = response.getWriter();
try {
// and use it like you would use System.out. Only, this stuff gets sent
//to the client
out.println("GET METHOD CALLED");
} finally {
// housekeeping: ensure that the Writer is closed when you're ready.
out.close();
}
}
In some cases it's easier to use a Stream. That's also possible but you can never have both the Writer and the OutputStream open simultaneously.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/plain;charset=UTF-8");
// ask the response object for an OutputStream object
OutputStream os = response.getOutputStream();
try {
// output some stuff, here just the characters ABC
os.write(new byte[]{65,66,67});
} finally {
os.close();
}
}
If you want to know more, there are loads of tutorials about servlets available on the web, including the Servlet chapter of the official Java EE tutorial on oracle.com
I have an Excel file on the server side. How I can display it on client side browser using servlets?
Thanks in advance.
To the point: just get an InputStream of it somehow (FileInputStream is suitable) and write it to the OutputStream of the response the usual Java IO way. That's basically all. You'll only need to take care that you set the right response headers, so that the browser understands what to do with it. The Content-Type header will instruct the webbrowser what kind of file it is so that the browser knows which application to use to open it.
Here's a kickoff example:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = URLDecoder.decode(request.getPathInfo(), "UTF-8");
File file = new File("/path/to/files", filename);
response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", file.length());
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file));
output = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[8192];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
} finally {
if (output != null) try { output.close(); } catch (IOException ignore) {}
if (input != null) try { input.close(); } catch (IOException ignore) {}
}
}
Map this servlet in web.xml on an url-pattern of /files/* so that you can get the excel file by http://example.com/contextname/files/filename.xls.
If it's actually an xlsx file, which isn't by default recognized by the average servletcontainer yet (the ServletContext#getMimeType() would then return application/octet-stream instead of the desired xlsx content type), then you need to add the following entry to the web.xml as well:
<mime-mapping>
<extension>xlsx</extension>
<mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
</mime-mapping>
For a more advanced example of a file servlet you may find this article useful as well, it supports under each download resumes as well.