I am creating a web application using EJBs and servlets. I have a page which displays a list of all items in the database. I would like to provide an option for the user to click on one of these items and this opens the SHOW servlet which gathers info regarding the item onto the page. I do not want to create a page for every single item. Instead I would like to create ONE SHOW servlet which can be used for all items. I am not sure how to provide this option through clicking on the name of an item, and also how to send the parameters...since it depends on what item the user chose.
Can someone help me please?
Thank you
When you generate the product listing, you can just make the IDs of all the database items parameters in the link.
Product Foo
Then in the doGet() method of your ShowProduct servlet, you can call the HttpServletRequest.getParameterValues() method to get that parameter's values and do the lookup in your database.
e.g.
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String[] params = request.getParameterValues("productID");
String productID = params[0];
...
}
Pass the unique ID of the item into the SHOW servlet. Then get that item's data from the DB and create your new page with that data.
Try having the show link point to your show servlet like this:
"/ShowServlet?itemID="+itemID
Related
I'm trying to implement a basic web application from the values that we are getting from web-service, it will include two datatables, each of them need to be populated in server-side.
For example, web-service have a structure like this ( Let's say these are books)
Firstly i am getting the string GUID value for the objects that i want to get an information, after that i am sending a request with the parameter of this GUIDs to service to get information XML for these book objects that includes name, page and author of them.
But as an important information, my servlet needs to get these values dynamically as soon as the page of datatable is changed, if this datatable will include 30 book ( i will get the 30 guid firstly so i can clarify that ) after that, send one request for 10 of them to show them on first page of datatable, if user clicked on page two, server behind needs to send request for the other group of ten and returns me result to show on the table.
I tried to implement the structure below :
http://www.codeproject.com/Articles/359750/jQuery-DataTables-in-Java-Web-Applications#ServerSideProcessing
but it populates a table with the DataRepository ones with all of them, so with this point of view i can't use it dynamically as i totally requested.
The main need for this, XML return for many objects needs so long time.
So do you know any example link or tutorial such a need for this ?
Thank you for informations in advance!
#Hayra, thanks for providing the Code Project link to the JQuery-DataTable example, it is very helpful. This is something that I might implement soon.
What I understood from the example, the JQuery-DataTable keeps track for you specific parameters that will allow you to return the exact number of records. The specific parameters that you need are "iDisplayStart" and the iDisplayLength". The "iDisplayLength" is set when the user specifies 10 records per page and the iDisplayStart, will is set when the page number changes.
So look at the code in the Code Project example doGet Method, this section of the code returns only the subset of records back to your table.
JQueryDataTableParamModel param = DataTablesParamUtility.getParam(request);
if(companies.size()< param.iDisplayStart + param.iDisplayLength) {
companies = companies.subList(param.iDisplayStart, companies.size());
} else {
companies = companies.subList(param.iDisplayStart, param.iDisplayStart + param.iDisplayLength);
}
try {
JsonObject jsonResponse = new JsonObject();
jsonResponse.addProperty("sEcho", sEcho);
jsonResponse.addProperty("iTotalRecords", iTotalRecords);
jsonResponse.addProperty("iTotalDisplayRecords", iTotalDisplayRecords);
for(Company c : companies){
JsonArray row = new JsonArray();
row.add(new JsonPrimitive(c.getName()));
row.add(new JsonPrimitive(c.getAddress()));
row.add(new JsonPrimitive(c.getTown()));
data.add(row);
}
jsonResponse.add("aaData", data);
response.setContentType("application/Json");
response.getWriter().print(jsonResponse.toString());
} catch (JsonIOException e) {
e.printStackTrace();
response.setContentType("text/html");
response.getWriter().print(e.getMessage());
}
I hope this help
In my web page after a chain of actions the client sees the details of the reservation. The method used to populate the data to be displayed in these details also stores the reservation in the database:
#RequestMapping(params = { "complete" }, method = RequestMethod.POST, produces = "text/html")
public String completeReservation(Model uiModel, HttpServletRequest httpServletRequest, ...) {
// ...
reservation.persist();
// ...
uiModel.addAttribute(...);
uiModel.addAttribute(...);
// ...
return "reservations/success";
}
The success page is the one that displays the details.
However, if I refresh the page another reservation entry is stored and I don't want this to happen.
Any suggestions on how I should approach this problem?
Commonly this is solved by making two actions - one that's doing the business (stores a reservation) and second one that shows the result to the user.
After successfull storing of reservation in the first action, redirect to the second one. From user point of view it will be one action and if he hits the reload button, only view action is performed again.
The scenario is such that i am accepting a unicode string from user on webpage and on click of the submit button the control moves to the next page where the complete logic of processing the string is written using a bean class at the same time i m inserting the string into the database by giving call to function of DAO class from inside bean class so as to maintain the log.
the problem is that when user refreshes the result page the bean class is getting called again and again and hence the same string is getting inserted into the database by the same user several times.
what should i do such that string inserted by the same user gets inserted into database only when user presses the submit button not while refreshing the result page.
or should i maintain the cookies with string as values from the user and check it when page gets loaded.
i am trying to maintain cookies at client side for the string that was previously entered by the user and check it accordingly
private void fnSetCookieValues(HttpServletRequest request,
HttpServletResponse response) {
Cookie[] cookies=request.getCookies();
for (int i = 0; i < cookies.length; i++) {
System.out.println("" + cookies.length + "Name" + cookies[i].getName());
if(cookies[i].getName().equals("DNString")) {
System.out.println("Inside if:: " + cookies[i].getValue() +
"" + cookies.length);
cookies[i].setValue(request.getParameter("txtString"));
} else {
Cookie ck = new Cookie("DNString", ";");
response.addCookie(ck);
}
}
}
This piece of code is written in servlet which gets called on submit button click
but each processing of this servlet displays 1NameJSESSIONID it is not showing the cookie DNString
Can anybody figure out the mistake i am doing?
you are looking into a way to prevent double-submits?
There are a couple of approaches, depending on your security needs and the frameworks you are using:
Java Script
Tokens
Synchronization
Google around a bit. There are many many solutions out there.
Thanks,
M
It is not good approach to check whether data is already entered or not.
So, One of the easy solution to this problem is to use HTTP redirect after the form submission from your servlet.Let say to success.jsp. Hence the form is not submitted again.
You can also reset your form once you get response.
For More check here
I have two portlets on my web page :
The first one is a web content portlet that allows picking up an article and displays it.
The other one is the portlet I'm working on (Struts MVC).
What I want to do in the second portlet is to get the article id used to display the web content in the first portlet.
Is it possible ?
Thank you!
You can do it using some Liferay specific APIs, though the approach is not perfect, but it'll work.
You can use Liferay APIs to get list of portlets currently available on page. Then you can figure out by portlet IDs which portlets are of type WebContentDisplay. Then you can read their preferences and there will be the ID of WebContent Article they display.
Note however that there can be cases when you have more then one WebContent Display portlet on page, or have none of them. You can either read list of portlets on the page on each render, or you can make a config page where you can display a select box for site admin to choose what WebContent Display Portlet instance should the value be taken from.
Let me show you the code for the first option, and second option if you'll need it I suppose you will deduce how to implement it from given code sample (mind the comments):
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.model.PortletConstants;
import com.liferay.portal.model.PortletPreferences;
import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portlet.PortletPreferencesFactoryUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import java.io.IOException;
import java.util.List;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
/**
* Portlet implementation class WCDPrefReaderPortlet
*/
public class WCDPrefReaderPortlet extends MVCPortlet {
public void doView(RenderRequest request, RenderResponse response)
throws IOException, PortletException {
// Obtain Liferay's ThemeDisplay object (typical operation in Liferay)
ThemeDisplay themeDisplay = (ThemeDisplay) request
.getAttribute(WebKeys.THEME_DISPLAY);
// Get ID of current page
long plid = themeDisplay.getPlid();
try {
// Obtain portlets on current page as list of
// com.liferay.portal.model.PortletPreferences
List<PortletPreferences> pagePortlets = PortletPreferencesLocalServiceUtil
.getPortletPreferencesByPlid(plid);
for (PortletPreferences portlet : pagePortlets) {
// Portlet ID
String portletId = portlet.getPortletId();
// WebContent Display portlet has ID 56. Also it's instanceable,
// so we expect instance ID to be present, i.e.
// 56_INSTANCE_NWWDuJPL64xa
// 56_INSTANCE_N1m7pQGwcScG
// would be IDs of WebContent Display portlet
// PortletConstants.getRootPortletId(portletId) will return
// portlet ID part without instance ID. I.e. we expect just "56"
if ("56".equals(PortletConstants.getRootPortletId(portletId))) {
// If we would have portlet ID stored, we could load it's
// preferences using this code:
// PortletPreferencesLocalServiceUtil.getPortletPreferences(plid,
// portletId);
// Not needed for now, since we already have the
// corresponding
// com.liferay.portal.model.PortletPreferences object
// Here we get portlet preferences as XML -
// Liferay stores them that way
String prefsAsXml = portlet.getPreferences();
// Parsing XML and creating Portlet API PortletPreferences
// object
javax.portlet.PortletPreferences prefs = PortletPreferencesFactoryUtil
.fromDefaultXML(prefsAsXml);
// Read preference named "articleId" - WebContent Display
// Portlet uses this preference to store articleId
String articleId = prefs.getValue("articleId", null);
// Do something with the articleId value
System.out.println(articleId);
}
}
} catch (SystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.doView(request, response);
}
}
Yes, you can share data between two different portlets by setting it in session. Set the article ID by editing the portlet code (of 1st portlet), set it in the session and retrieve it in you portlet.
For setting and getting values (Inter portlet communication) example-->Check this
In the Java Servlet, how to include original paramters after response ?
Servlet
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cmd = request.getParameter("cmd");
System.out.println("service , cmd="+cmd);
request.setAttribute("name", "John"+System.currentTimeMillis());
RequestDispatcher rd = request.getRequestDispatcher("process.jsp");
rd.include(request, response);
}
JSP
main ${name}<br>
cmd ${cmd}
If I want to include all paramters, like "cmd", to a new jsp page, how to do it ?
based on No.1, if I want to add NEW attributes, like "name" to a new jsp page, how to do it ?
In the above codes, use include or forward, the results are same. why ?
Thanks
If I want to include all paramters, like "cmd", to a new jsp page, how to do it ?
All request parameters are in EL available by the ${param} map.
${param.cmd}
You don't need to prepare anything in the servlet.
based on No.1, if I want to add NEW attributes, like "name" to a new jsp page, how to do it ?
You already did it by request.setAttribute("name", name) and ${name}.
In the above codes, use include or forward, the results are same. why ?
Not exactly. If you use include(), the delegatee would not be able to control the response headers. You should be using forward() in this case. See also the javadoc. You should use include() only if you want to append something before and after instead of fully delegating the request/response.
See also:
Our Servlets wiki page
How do I execute multiple servlets in sequence?
It's the same request, you don't need to do anything at all.
A forward means you can't have committed any response (no output to client). Include doesn't allow any response status code or header changes.
See the docs for forward/include.
you can access all the request params using the request.getParameterMap() another question which can help you method, this returns a map of all params (key-value pair) which you can iterate and set the attribute.
request.setAttribute("name", "John"+System.currentTimeMillis());
What you've done here does add a new attribute called name (provided another entry doesn't exist with the key as name).
The result of include and forward are the same as
you are not adding any specific content to the response
when you forward a request, you are forwarding the control to handle the response to another component (in your case process.jsp)
when you include a jsp in your request, you are executing the included component and have the option of adding something extra to the stream (which you aren't doing).
thats why both the actions show you the same result.