I have implemented JCaptcha in my web application and it works fine but when cookies of the browser is blocked it always fail and return false.
the servlet code is as follows:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userCaptchaResponse =request.getParameter("jcaptcha");
boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse(request, userCaptchaResponse);
if(captchaPassed){
System.out.println("success!!"+userCaptchaResponse);
RequestDispatcher rd=request.getRequestDispatcher("Result.jsp");
rd.forward(request, response);
//response.sendRedirect("Result.jsp");
}else{
System.out.println("failure!!"+userCaptchaResponse);
response.sendRedirect("Index.jsp"+"?id=false");
}
}
and code in jsp page is
<tr align="center">
<td align="right" width="33%"><img height="60px" width="140px" src="jcaptcha.jpg" /></td>
<td align="left" width="33%" valign="middle"><input type="text" name="jcaptcha" value="" /></td>
</tr>
I want my captcha to work irrespective of whether the cookies are blocked or not!!!
is there any solution for this or any other method to implement captcha in java
I am using jdk 1.7 and tomcat 7 as runtime environment.
The problem with your captcha lookup is that it relies on a User session. Which is in my opinion a design flaw. If cookies are blocked the session will not be linked to the user.
There are other libraries e.g. SimpleCatcha. Or other services like recaptcha.
Basically if you have a library which generates you a captcha you might implement it like this as pseudo algorithm which is not session dependent:
For every form including a captcha:
Generate temporary captcha
Generate a hard to guess and unique identifier (maybe with a uuid).
Link the unique identfier with the correct answer server side and persist it temporarily
Provide the unique identifier in the generated form
If a user sends the form he will provide the guess and the uuid you might lookup this pair on your server side.
Invalidate the UUID and the Image wether or not the user entered the correct answer.
If this is too slow from a performance perspective you might consider to have a background process to fill up a fixed size FILO container/queue to hold precomputed captchas.
JCaptcha doesn't work if the cookies are disabled. There is a bug: http://jcaptcha.octo.com/jira/browse/JASTR-3
You can try another library, for example recaptcha.
Related
I am working on DXP portal 7.2 and creating a CRUD application (Course) w Service Builder. When Delete task is performed on my data table, it works fine however the portal page is redirecting to a non available mode, example it says: Course is temporarily unavailable.
Please let me know what part I am doing wrong. thank you so much!
My view.jsp Delete part looks like this:
<%-- Delete action. --%>
<td>
<liferay-portlet:renderURL var="deleteURL">
<liferay-portlet:param name="mvcRenderCommandName" value="<%=ConstantsCommands.DELETE_COURSE %>"/>
<liferay-portlet:param name="backURL" value="<%= currentURL %>"/>
<liferay-portlet:param name="courseId" value="<%=
String.valueOf(course.getCourseId()) %>"/>
</liferay-portlet:renderURL>
<liferay-ui:icon-menu>
<liferay-ui:icon url="${deleteURL }" message="delete" >
</liferay-ui:icon>
</liferay-ui:icon-menu>
</td>
</tr>
Below is my MVC Render command Snippet for my Delete:
public class CourseDeleteMVCRenderCommand implements MVCRenderCommand{
#Override
public String render(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException {
long courseId = ParamUtil.getLong(renderRequest, "courseId");
try {
// Call service to delete the course.
_courseService.deleteCourse(courseId);
// Set success message.
SessionMessages.add(renderRequest, "courseDeleted");
}catch (PortalException pe) {
// Set error messages from the service layer.
SessionErrors.add(renderRequest, "serviceErrorDetails", pe);
}
return null;
}
#Reference
protected CourseService _courseService;
}
Use MVCRenderCommand and liferay-portlet:actionURL, using render url is possible but wrong.
The error comes from missing mvcPath paramenter in renderURL. Liferay does not know the destination jsp.
Some sample here
jsp: https://github.com/liferay/com-liferay-commerce/blob/abf23f6175549f302f8b18ce5c0407c969a2e7bd/commerce-subscription-web/src/main/resources/META-INF/resources/subscription_entry_action.jsp
action class: https://github.com/liferay/com-liferay-commerce/blob/abf23f6175549f302f8b18ce5c0407c969a2e7bd/commerce-subscription-web/src/main/java/com/liferay/commerce/subscription/web/internal/portlet/action/EditCommerceSubscriptionContentMVCActionCommand.java
Most important: "Thou shalt not change state in a render operation."
You're looking for an actionURL, and an MVCActionCommand to execute the operation (change state). Potentially a separate render, but that's often prior to the action (e.g. showing a particular option, with the possibility to delete it (if you don't have the delete button on your main UI)
Implementing a destructive operation within a UI rendering is just wrong and I'd recommend to go through any tutorial you find to learn the difference between action- and render-phase in a portlet. They're separated for a reason.
Typically, right after an actionCommand is executed, the UI is rendered.
On top, quite a critical part of a MVCRenderCommand as well as an MVCActionCommand is the #Component annotation (assuming you're taking the OSGi route)
I've got an Enum class that stores the name and some relevant numbers for 10 different materials.
In my HTML page I want to select one material via a drop down. Therefore I iterate over them via JSTL. I used to have a scriplet for that but I replaced it now. This is my code:
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
if (session.getAttribute("materialArray") == null) {
session.setAttribute("materialArray", Material.values());
}
request.getRequestDispatcher("/jsp/input.jsp").forward(request, response);
}
JSP-Page:
{...}
<h2>
<fmt:message key="input.label.material" />
</h2>
<select name="s_material" id="s_material">
<c:set var="MaterialEnum" value="${materialArray}" />
<c:forEach items="${MaterialEnum}" var="material">
<option value="${material}"><c:out
value="${material.description}"></c:out></option>
</c:forEach>
</select>
{...}
Problem: When I click 'Run project on server' in eclipse and visit the URL in Chrome it works fine.
But when I export the project to a WAR file and deploy it on a server (same tomcat version, different machine) the drop down doesn't fill and I get a NullPointerException for Material.values(). Also when I look at it in the eclipse intern browser, the material drop down menu isn't filled. (I used System.out.println() in doGet() to check if it does anything, it only prints the materials when accessing the page via Chrome. In internal browser it simply prints nothing.)
Why? Is there a way to bypass these enum-methods .values() and .valueOf() (which I use later to process the selected value from the drop down)? Are there differences in when doGet() is called?
(The scriplet I used before worked in both environments.)
I've developed an HTML page that sends information to a Servlet. In the Servlet, I am using the methods doGet() and doPost():
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
In the html page code that calls the Servlet is:
<form action="identification" method="post" enctype="multipart/form-data">
User Name: <input type="text" name="realname">
Password: <input type="password" name="mypassword">
<input type="submit" value="Identification">
</form>
When I use method = "get" in the Servlet, I get the value of id and password, however when using method = "post", id and password are set to null. Why don't I get the values in this case?
Another thing I'd like to know is how to use the data generated or validated by the Servlet. For example, if the Servlet shown above authenticates the user, I'd like to print the user id in my HTML page. I should be able to send the string 'id' as a response and use this info in my HTML page. Is it possible?
Introduction
You should use doGet() when you want to intercept on HTTP GET requests. You should use doPost() when you want to intercept on HTTP POST requests. That's all. Do not port the one to the other or vice versa (such as in Netbeans' unfortunate auto-generated processRequest() method). This makes no utter sense.
GET
Usually, HTTP GET requests are idempotent. I.e. you get exactly the same result everytime you execute the request (leaving authorization/authentication and the time-sensitive nature of the page —search results, last news, etc— outside consideration). We can talk about a bookmarkable request. Clicking a link, clicking a bookmark, entering raw URL in browser address bar, etcetera will all fire a HTTP GET request. If a Servlet is listening on the URL in question, then its doGet() method will be called. It's usually used to preprocess a request. I.e. doing some business stuff before presenting the HTML output from a JSP, such as gathering data for display in a table.
#WebServlet("/products")
public class ProductsServlet extends HttpServlet {
#EJB
private ProductService productService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
Note that the JSP file is explicitly placed in /WEB-INF folder in order to prevent endusers being able to access it directly without invoking the preprocessing servlet (and thus end up getting confused by seeing an empty table).
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td>detail</td>
</tr>
</c:forEach>
</table>
Also view/edit detail links as shown in last column above are usually idempotent.
#WebServlet("/product")
public class ProductServlet extends HttpServlet {
#EJB
private ProductService productService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Product product = productService.find(request.getParameter("id"));
request.setAttribute("product", product); // Will be available as ${product} in JSP
request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
}
}
<dl>
<dt>ID</dt>
<dd>${product.id}</dd>
<dt>Name</dt>
<dd>${product.name}</dd>
<dt>Description</dt>
<dd>${product.description}</dd>
<dt>Price</dt>
<dd>${product.price}</dd>
<dt>Image</dt>
<dd><img src="productImage?id=${product.id}" /></dd>
</dl>
POST
HTTP POST requests are not idempotent. If the enduser has submitted a POST form on an URL beforehand, which hasn't performed a redirect, then the URL is not necessarily bookmarkable. The submitted form data is not reflected in the URL. Copypasting the URL into a new browser window/tab may not necessarily yield exactly the same result as after the form submit. Such an URL is then not bookmarkable. If a Servlet is listening on the URL in question, then its doPost() will be called. It's usually used to postprocess a request. I.e. gathering data from a submitted HTML form and doing some business stuff with it (conversion, validation, saving in DB, etcetera). Finally usually the result is presented as HTML from the forwarded JSP page.
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="login">
<span class="error">${error}</span>
</form>
...which can be used in combination with this piece of Servlet:
#WebServlet("/login")
public class LoginServlet extends HttpServlet {
#EJB
private UserService userService;
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect("home");
}
else {
request.setAttribute("error", "Unknown user, please try again");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
You see, if the User is found in DB (i.e. username and password are valid), then the User will be put in session scope (i.e. "logged in") and the servlet will redirect to some main page (this example goes to http://example.com/contextname/home), else it will set an error message and forward the request back to the same JSP page so that the message get displayed by ${error}.
You can if necessary also "hide" the login.jsp in /WEB-INF/login.jsp so that the users can only access it by the servlet. This keeps the URL clean http://example.com/contextname/login. All you need to do is to add a doGet() to the servlet like this:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(and update the same line in doPost() accordingly)
That said, I am not sure if it is just playing around and shooting in the dark, but the code which you posted doesn't look good (such as using compareTo() instead of equals() and digging in the parameternames instead of just using getParameter() and the id and password seems to be declared as servlet instance variables — which is NOT threadsafe). So I would strongly recommend to learn a bit more about basic Java SE API using the Oracle tutorials (check the chapter "Trails Covering the Basics") and how to use JSP/Servlets the right way using those tutorials.
See also:
Our servlets wiki page
Java EE web development, where do I start and what skills do I need?
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
Update: as per the update of your question (which is pretty major, you should not remove parts of your original question, this would make the answers worthless .. rather add the information in a new block) , it turns out that you're unnecessarily setting form's encoding type to multipart/form-data. This will send the request parameters in a different composition than the (default) application/x-www-form-urlencoded which sends the request parameters as a query string (e.g. name1=value1&name2=value2&name3=value3). You only need multipart/form-data whenever you have a <input type="file"> element in the form to upload files which may be non-character data (binary data). This is not the case in your case, so just remove it and it will work as expected. If you ever need to upload files, then you'll have to set the encoding type so and parse the request body yourself. Usually you use the Apache Commons FileUpload there for, but if you're already on fresh new Servlet 3.0 API, then you can just use builtin facilities starting with HttpServletRequest#getPart(). See also this answer for a concrete example: How to upload files to server using JSP/Servlet?
Both GET and POST are used by the browser to request a single resource from the server. Each resource requires a separate GET or POST request.
The GET method is most commonly (and is the default method) used by browsers to retrieve information from servers. When using the GET method the 3rd section of the request packet, which is the request body, remains empty.
The GET method is used in one of two ways:
When no method is specified, that is when you or the browser is requesting a simple resource such as an HTML page, an image, etc.
When a form is submitted, and you choose method=GET on the HTML tag. If the GET method is used with an HTML form, then the data collected through the form is sent to the server by appending a "?" to the end of the URL, and then adding all name=value pairs (name of the html form field and value entered in that field) separated by an "&"
Example:
GET /sultans/shop//form1.jsp?name=Sam%20Sultan&iceCream=vanilla HTTP/1.0 optional headeroptional header<< empty line >>>
The name=value form data will be stored in an environment variable called QUERY_STRING.
This variable will be sent to a processing program (such as JSP, Java servlet, PHP etc.)
The POST method is used when you create an HTML form, and request method=POST as part of the tag. The POST method allows the client to send form data to the server in the request body section of the request (as discussed earlier). The data is encoded and is formatted similar to the GET method, except that the data is sent to the program through the standard input.
Example:
POST /sultans/shop//form1.jsp HTTP/1.0 optional headeroptional header<< empty line >>> name=Sam%20Sultan&iceCream=vanilla
When using the post method, the QUERY_STRING environment variable will be empty.
Advantages/Disadvantages of GET vs. POST
Advantages of the GET method:
Slightly faster
Parameters can be entered via a form or by appending them after the URL
Page can be bookmarked with its parameters
Disadvantages of the GET method:
Can only send 4K worth of data. (You should not use it when using a textarea field)
Parameters are visible at the end of the URL
Advantages of the POST method:
Parameters are not visible at the end of the URL. (Use for sensitive data)
Can send more that 4K worth of data to server
Disadvantages of the POST method:
Can cannot be bookmarked with its data
The servlet container's implementation of HttpServlet.service() method will automatically forward to doGet() or doPost() as necessary, so you shouldn't need to override the service method.
Could it be that you are passing the data through get, not post?
<form method="get" ..>
..
</form>
If you do <form action="identification" > for your html form, data will be passed using 'Get' by default and hence you can catch this using doGet function in your java servlet code. This way data will be passed under the HTML header and hence will be visible in the URL when submitted.
On the other hand if you want to pass data in HTML body, then USE Post: <form action="identification" method="post"> and catch this data in doPost function. This was, data will be passed under the html body and not the html header, and you will not see the data in the URL after submitting the form.
Examples from my html:
<body>
<form action="StartProcessUrl" method="post">
.....
.....
Examples from my java servlet code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
String surname = request.getParameter("txtSurname");
String firstname = request.getParameter("txtForename");
String rqNo = request.getParameter("txtRQ6");
String nhsNo = request.getParameter("txtNHSNo");
String attachment1 = request.getParameter("base64textarea1");
String attachment2 = request.getParameter("base64textarea2");
.........
.........
I have a doubt regarding the use of servlets.
In the application I'm building I use Html pages to ask the user for info.
Imagine a Html page that lets the user request to see on the screen the content of a data base. What I'm doing is:
1.- From the Html page I'm calling a servlet that will open a connection with the database.
2.- The servlet builds the web page that the user will see.
My question is: is there any other way of doing this? Do I have to build the web page in the servlet or is there any way of sending the information contained in the database to an .html file which will build the web page (in my case I need to show on the screen a table containing all the information) ?
Thanks
Servlets are meant to control, preprocess and/or postprocess requests, not to present the data. There the JSP is for as being a view technology providing a template to write HTML/CSS/JS in. You can control the page flow with help of taglibs like JSTL and access any scoped attributes using EL.
First create a SearchServlet and map it on an url-pattern of /search and implement doGet() and doPost() as follows:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Preprocess request here and finally send request to JSP for display.
request.getRequestDispatcher("/WEB-INF/search.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Postprocess request here. Get results from your DAO and store in request scope.
String search = request.getParameter("search");
List<Result> results = searchDAO.find(search);
request.setAttribute("results", results);
request.getRequestDispatcher("/WEB-INF/search.jsp").forward(request, response);
}
Here's how the JSP /WEB-INF/search.jsp would look like, it makes use of JSTL (just drop JAR in /WEB-INF/lib) to control the page flow.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<form action="search" method="post">
<input type="text" name="search">
<input type="submit" value="search">
</form>
<c:if test="${not empty results}">
<p>There are ${fn:length(results)} results.</p>
<table>
<c:forEach items="${results}" var="result">
<tr>
<td>${result.id}</td>
<td>${result.name}</td>
<td>${result.value}</td>
</tr>
</c:forEach>
</table>
</c:if>
Note that JSP is placed in /WEB-INF to prevent users from direct access by URL. They are forced to use the servlet for that by http://example.com/contextname/search.
To learn more about JSP/Servlets, I can recommend Marty Hall's Coreservlets.com tutorials. To learn more about the logic behind searchDAO, I can recommend this basic DAO tutorial.
To go a step further, you could always consider to make use of a MVC framework which is built on top of the Servlet API, such as Sun JSF, Apache Struts, Spring MVC, etcetera so that you basically end up with only Javabeans and JSP/XHTML files. The average MVC frameworks will take care about gathering request parameters, valitate/convert them, update Javabeans with those values, invoke some Javabean action method to process them, etcetera. This makes the servlet "superfluous" (which is however still used as being the core processor of the framework).
In addition to Servlets, Java has JSP pages, which are a mix of HTML and custom tags (including the Java Standard Tag Library or JSTL) which are eventually compiled into Servlets.
There are other technologies for making web applications, including things like Java Server Faces (JSF), Apache Struts, Spring, etc... Spring in particular is very widely used in modern web application development.
Ultimately, though, it's like Brian Agnew said... you have to communicate back and forth from the browser to the server. These are just various technologies to facilitate that.
Ultimately the browser has to send a request to the server for the database info. You can do this in many ways:
build the whole page in the servlet (perhaps the simplest)
build a page in the servlet containing (say) XML data, and the browser renders it into HTML (via XSL/Javascript etc.). That may be suitable if you want the browser to control the formatting and presentation.
build a page containing AJAX requests to go back to the server and get the data. That may be more suitable for data that updates regularly, or more interactive applications.
There are numerous ways to skin this cat. I suspect you're doing the simplest one, which is fine. I would tend towards this without explicit requirements that mean I need to do something else. Further requirements that complicate matters may include paging the data if there's too much to fit on the screen. All the solutions above can be made to incorporate this in some fashion.
My java is rusty but...
in your Data Access layer, iterate over the result set and build a custom object and insert it into an ArrayList;
class DataAccess {
public ArrayList foo() {
// Connect to DB
// Execute Query
// Populate resultSet
ArrayList result = new ArrayList();
while (resultSet.hasNext()) {
CustomObject o = new CustomObject();
o.setProperty1(resultSet.getInt(1));
o.setProperty2(resultSet.getString(2));
// and so on
result.add(o);
}
return result;
}
}
Call this method from your Servlet. After you have populated the ArrayList, put it on the Request object and forward on to your .jsp page
ArrayList results = DataAccessClass.foo();
Request.setAttribute("Results", results);
In your jsp, build your markup using scriptlets
<% foreach (CustomObject o in Request.getAttribute("Results"))
{%>
<td><%= o.getProperty1()</td>
<td><%= o.getProperty2()</td>
<% } %>
Good luck
For a customer, I need to write a Servlet which can print values in a form post. The form is hosted on another server and looks somewhat like this:
<form action="http://myserver/myServlet" method="POST">
<input type="text" id="someName" value="someInterestingValue"/>
<input type="submit" value="submit" />
</form>
I have a Tomcat 5.0.28 server available, running on a Java 1.4 jdk, so I made a simple servlet:
public class ProxyServlet extends HttpServlet {
public void doPost(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
PrintWriter out = res.getWriter();
Enumeration a =req.getAttributeNames();
while (a.hasMoreElements()){
String attrname = (String) a.nextElement();
out.println(attrname+"="+req.getAttribute(attrname)+"<br/>");
}
out.close();
}
}
When I go to the servlet by URL everything looks as expected. When I send a GET request with some parameters, I can see those as attributes in the debugger in the doGet() method (method was left out for brevety).
However, in the doPost(), my form fields seem to be missing. I've looked into the Tomcat logfiles, and nothing special is logged. I tried to add a crossdomain.xml to some directories but did not find a way to change this behaviour.
So to be clear: The Form as listed above is on server A. My servlet runs on an existing legacy Tomcat/Java application hosted on server B. When the form is of type "POST" none of the fields arrive at the Servlet on server B. Apache is NOT "in front" of Tomcat.
Is there some configuration setting I am missing in Tomcat?
Any tips or suggestions where to look next?
Help is greatly appreciated.
Request attributes? Don't you need to access them as request parameters using HttpServletRequest#getParameter() and so on?
Which adds more confusion is that you said that it works in the doGet(). How does its code look like then? Does it also access them as attributes? That would in a normal JSP/Servlet environment (i.e. you aren't using some filter which copies the parameters to attributes or so) have been impossible.
This has nothing to do with cross-site. As BalusC said, use getParameter... instead of getAttribute... methods
Found the problem. After a whole day of searching and coding, it all boils down to the fact that my code was working fine. The problem is in the form. the line:
<input type="text" id="someName" value="someInterestingValue"/>
Should read:
<input type="text" name="someName" value="someInterestingValue"/>
For people mentioning "getParameter" instead of "getAttribute" you are totally correct. In my test code I had both just to be sure (because I thought I lost it...) but both were not returning results, as the browser was simply not sending the name/value pairs.
I guess posting this on Stackoverflow did help, because I had to explain and re-read my problem I thought the "id=" looked funny. Coding is finding bugs in pieces of text you are overlooking...