I have written a Servlet something like this
public class ServletUtil extends HttpServlet {
private static final long serialVersionUID = 1571172240732862415L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String acInfo = request.getQueryString();
someDao dao = new someDao();
ArrayList<String> resultAutoComplete=dao.someResults(acInfo);
out.close();
}
}
I have an auto complete Object/wizard in front end and as the user types in it is making Ajax call to back end to grab the list of results. So I have written a Servlet and I am pulling the user input and getting my results from DAO layer.
My question here is how should I send this list(resultAutoComplete) to Front end in the Servlet?
I'd expect you to serialise this in some fashion such that the client understands it. e.g. perhaps using JSON or similar.
I note that your response content type is text/html. So why not simply write each element of your list to your Writer out, separated by (say) a <li> element (with the appropriate unordered/order list entities surrounding this)
Try this,
for (String str : resultAutoComplete)
{
out.println(str);
}
By serializing it to a String and writing it to out...
Seriously though, I wouldn't code at the low level Servlet spec. For this kind of return-this-pojo call I would use Spring 3's RESTful service libraries, or something similar.
No json! instead of going through a list in javascript, return a completed <li> lists and replace innerHTML of <ul>.The reason to do so is to give a better performance. Unless you want to do something more flexible, leave things to the back-end.
When do json, you gotta parse string into json object and then loop through and generate html, that's just an extra step. Keep things simple, plus, parsing string could be costly.
If you don't loop through the list and instead do out.println the list object, you would likely see the address. also, you need to generate html, so:
StringBuilder sb = new StringBuilder();
for(String option: options){
sb.append("<li>").append(option).append("</li>");
}
out.println(sb);
Related
I have a MarkLogic XQuery eval call that returns a lists of strings. I use the below code to process the results. I have another call that returns a list of Json Documents but I can't see how to get EvalResult to give me a JsonDocument document. How do I change the below code to process Json Documents?
public static ArrayList<String> getStringList(DatabaseClient client, String query)
{
ArrayList<String> strings = new ArrayList<String>();
ServerEvaluationCall eval = client.newServerEval();
EvalResultIterator eri = eval.xquery(query).eval();
while (eri.hasNext())
{
EvalResult er = eri.next();
String s = er.getString();
strings.add(s);
}
return strings;
}
First, let me suggest that you only use eval as a last resort as it may open a security hole. Injection attacks aren't possible if you never send code from the client to be executed on the server. Start first with the out-of-the-box features, and if those aren't enough, consider writing a resource extension instead of using eval. Two examples are ResourceExtension and JavascriptResourceExtension.
But to answer your question, change this:
String s = er.getString();
to this:
JacksonHandle handle = er.get(new JacksonHandle());
JsonNode json = handle.get();
or this shortcut:
JsonNode json = er.getAs(JsonNode.class);
For a complete example, see handling of myArray and myObject EvalTest.evalAndInvokeXQuery (and of course, runAndTestXQuery) and evaltest.xqy.
These Jackson handles work the same whether you're getting JSON results from a document read, search, or eval. You can read more about the io shortcuts here. For more sample code with Jackson, see JacksonHandleExample, JacksonHandleTest, JacksonStreamTest, and JacksonDatabindTest.
I have a simple JSR 286 Portlet that displays a user manual (pure HTML code, not JSP).
Actually, my doView method, just contains this :
public class UserManualPortlet extends GenericPortlet
{
#Override
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(
"/html/usermanual.html");
rd.include(request, response);
}
}
This works as expected, however I'm having trouble when including images. I'm aware that the path to images should be something like :
<img src='<%=renderResponse.encodeURL(renderRequest.getContextPath() + "/html/image.jpg")%>'/>
However, my HTML file containing the user manual is used elsewhere, so I would like to preserve it as a pure HTML file.
Is there a way to dynamically replace my classic images urls by something like the example above ? Perhaps using the PrintWriter of the response ?
If such thing is not possible, I thing I would need to generate a JSP file during my Maven build.
Any solution or ideas are welcome.
With JSR-268 portlets you have a better way of referencing resources: create ResourceURL using renderResponse.createResourceURL() and then you set the resourceID in the ResourceURL. That should give more consistent results across all portlet containers.
That said, if you want to modify the generated content from your usermanual.html but you don't want to convert it to a JSP then, instead of using a request dispatcher, I would load the file contents on my own, parse it at the same time that I do the URL replacements and then print all the contents to the portlet's response.
I have some JavaScript which I want to perform a REST Request (GET) to my servlet.
The format of the record I want to send is in the following format ...
/id1/vara/varb/varc/timedelta1,timedelta2,timedelta3,....,timedeltaN/
So basically there would be 5 attributes in each record I send. I need to batch these up - I'm sending multiple records in a single GET Request. My Get URL might look a little like the following.
myservletname/id1/vara/varb/varc/timedelta1,timedelta2,timedelta3/id2/vara/varb/varc/timedelta1,timedelta2,timedelta3/id3/vara/varb/varc/timedelta1,timedelta2,timedelta3/
I'm aware on the limit of around 2000 chars in the URL String so to keep things safe I'll ensure the length of the URL is less than this.
In the above example 3 records were sent to the servlet.
I'm wondering how I might process these on the server end. Havent really worked with REST before in Java. What do I need to do on the server end to process these URLs to extract the data ?
Thanks
Basically
public class RestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String uri = request.getPathInfo();
Pattern p = Pattern.compile(
"/([^/]+)/([^/]+)/([^/]+)/([^/]+)/(\d+)(?:,(\d+))*/"
);
Matcher m = p.matcher(uri);
if (m.matches()) {
String id = m.group(1);
String vara = m.group(2);
String varb = m.group(3);
String deltas = m.group(4);
// etc
}
}
}
It's not a very good model for how to do it, but it is simple and understandable for someone not familiar with Servlets
You can use JAX-RS or Restlets instead of a servlet
You should seriously consider using POST instead of GET for this. REST (and URLs) weren't designed for this purpose.
I have a web application that can display a generated PDF file to the user using the following Java code on the server:
#Path("MyDocument.pdf/")
#GET
#Produces({"application/pdf"})
public StreamingOutput getPDF() throws Exception {
return new StreamingOutput() {
public void write(OutputStream output) throws IOException, WebApplicationException {
try {
PdfGenerator generator = new PdfGenerator(getEntity());
generator.generatePDF(output);
} catch (Exception e) {
logger.error("Error getting PDF file.", e);
throw new WebApplicationException(e);
}
}
};
}
This code takes advantage of the fact that I only need so much data from the front end in order to generate the PDF, so it can easily be done using a GET function.
However, I now want to return a PDF in a more dynamic way, and need a bunch more information from the front end in order to generate the PDF. In other areas, I'm sending similar amounts of data and persisting it to the data store using a PUT and #FormParams, such as:
#PUT
#Consumes({"application/x-www-form-urlencoded"})
public void put(#FormParam("name") String name,
#FormParam("details") String details,
#FormParam("moreDetails") String moreDetails...
So, because of the amount of data I need to pass from the front end, I can't use a GET function with just query parameters.
I'm using Dojo on the front-end, and all of the dojo interactions really don't know what to do with a PDF returned from a PUT operation.
I'd like to not have to do this in two steps (persist the data sent in the put, and then request the PDF) simply because the PDF is more "transient" in this uses case, and I don't want the data taking up space in my data store.
Is there a way to do this, or am I thinking about things all wrong?
Thanks.
I can't quite understand what do you need to accomplish - looks like you want to submit some data to persist it and then return pdf as a result? This should be straightforward, doesn't need to be 2 steps, just submit, on the submit save the data and return PDF.
Is this your problem? Can you clarify?
P.S.
Ok, you need to do the following in your servlet:
response.setHeader("Content-disposition",
"attachment; filename=" +
"Example.pdf" );
response.setContentType( "application/pdf" );
Set the "content-length" on the response, otherwise the Acrobat Reader plugin may not work properly, ex. response.setContentLength(bos.size());
If you provide output in JSP you can do this:
<%# page contentType="application/pdf" %>
I am trying to use a RequestDispatcher to send parameters from a servlet.
Here is my servlet code:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String station = request.getParameter("station");
String insDate = request.getParameter("insDate");
//test line
String test = "/response2.jsp?myStation=5";
RequestDispatcher rd;
if (station.isEmpty()) {
rd = getServletContext().getRequestDispatcher("/response1.jsp");
} else {
rd = getServletContext().getRequestDispatcher(test);
}
rd.forward(request, response);
}
Here is my jsp, with the code to read the value - however it shows null.
<h1>response 2</h1>
<p>
<%=request.getAttribute("myStation") %>
</p>
Thanks for any suggestions.
Greener
In your servlet use request.setAttribute in the following manner
request.setAttribute("myStation", value);
where value happens to be the object you want to read later.
and extract it later in a different servlet/jsp using request.getAttribute as
String value = (String)request.getAttribute("myStation")
or
<%= request.getAttribute("myStation")%>
Do note that the scope of usage of get/setAttribute is limited in nature - attributes are reset between requests. If you intend to store values for longer, you should use the session or application context, or better a database.
Attributes are different from parameters, in that the client never sets attributes. Attributes are more or less used by developers to transfer state from one servlet/JSP to another. So you should use getParameter (there is no setParameter) to extract data from a request, set attributes if needed using setAttribute, forward the request internally using RequestDispatcher and extract the attributes using getAttribute.
Use getParameter(). An attribute is set and read internally within the application.
In your code,
String test = "/response2.jsp?myStation=5";
You are adding myStation=5 as query string.As the query string parameters are stored
as request parameters in Request Object.
Therefore you can use ,
It works fine.Thanks.