I'm new in the Java world. I am trying to develop an ACME Demo using a simple CSV file as a database to validate user names and passwords. I wonder if it is possible to make some hyperlinks on the index.jsp page, which will take you to other jsp pages of the same website if you click them. As far as I know hyperlinks will invoke the doGet method inside the servle, where -in my case- you gonna be redirected to those secure jsp if your credentials are valid of course. So it has worked for just one hyperlink and I would like to make things more dynamic no matter how many links are there??!!
jsp
Content1
<!-- Here I would like to add more links -->
Servlet
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
//response.sendRedirect("login.jsp");
HttpSession session= request.getSession(true);
if ((session.getAttribute("userSession") != null) && (session.getAttribute("userSession").equals(session.getId())))
{
response.sendRedirect("content1.jsp");
// How can my doGet method manage multiple links here?
}
else
{
response.sendRedirect("login.jsp");
}
}
You should use a servlet filter.
A filter is a component that will be invoked for all the requests to a given url-mapping, and/or for all the requests to a given servlet.
The filter can then check if the user is logged in. If he's loged in, it asks the container to proceed, i.e. invoke the target servlet as if there was no filter. If he's not logged in, the filter can return an error, or redirect to a login page, or do whatever it wants.
See http://www.oracle.com/technetwork/java/filters-137243.html for an introduction and examples of servlet filters.
Related
I need to make a Servlet which will manage some information and, after that, will go to a Liferay 6.2 Portlet. Both in the same server.
I need the Servlet to send a parameter, but I don't want to send it GET, but POST method. So, I try to put it in the session to retrieve it from the Portlet.
At the Servlet, I have:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
request.getSession().setAttribute("param1", "TEST 1");
url = "http://myServer/";
response.sendRedirect(response.encodeRedirectURL(url));
} catch (Exception e) {
e.printStackTrace();
}
}
And at the Portlet I manage the information at render method, as I want to get param1 before I render the page:
public void render (RenderRequest renderRequest, RenderResponse renderResponse)
throws PortletException, IOException {
super.render(renderRequest, renderResponse);
//Try to retrieve from getOriginalServletRequest
HttpServletRequest servletReq = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
String param1 = servletReq.getSession().getAttribute("param1").toString();
//Try to retrieve from getHttpServletRequest
HttpServletRequest servletReq_ = PortalUtil.getHttpServletRequest(renderRequest);
String param1_ = servletReq_.getSession().getAttribute("param1").toString();
}
As you can see, I tried to retrieve from getHttpServletRequest and from getOriginalServletRequest, but I always get the param1 null.
Any suggestion?
Thank you in advance!
Update question:
I'm being called from a third part, and I'm receiving a GET parameter I want to evaluate.
After that, and not rendering a page in the middle, I want to redirect to one or another Portlet, depending of that evaluation.
I need to send some personal information to those Portlets, so I want to send some parameters in POST method.
A Servlet doesn't fit as doesn't share session with Portlets.
I've tried to implement a landing Portlet, but the redirect can only be done in action phase, so I'd need to render a (empty) page before the redirect, don't like that part. Render phase doesn't allow redirect (even getting PortalUtil.getHttpServletResponse(), doesn't work)
Any suggestion? Thanks!
A servlet and a portlet will not share the same session. The portlet is living within the portal server, e.g. Liferay. The servlet is typically in its own web application, thus completely separated by design.
If you need to communicate between the two, here are two possible solutions/workarounds:
reimplement your servlet as a portlet, potentially utilizing the resource-phase of a portlet
use a request parameter instead of a session attribute
Edit after all of the comments:
It seems best to take a step back and look at the underlying problem - what is the problem that you're actually trying to solve? The content of your question is how you're trying to solve it, and obviously there are challenges. It looks like the problem needs a different solution in the first place.
My answer describes why your solution can't work, but that obviously doesn't help solving the underlying problem.
I have a webpage I am currently building for an internal work tool. It is a sample website that allows a user to login and then execute query from the database. I just implemented a filter to re-direct not-logged in users to the login page. The doFilter function looks like this
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("user") == null) {
// No logged-in user found, so redirect to login page.
response.sendRedirect(request.getContextPath() + "/Login.jsp");
} else {
// Logged-in user found, so just continue request.
chain.doFilter(req, res);
}
}
In my web.xml I have
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>Servlets.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/Home.jsp</url-pattern>
</filter-mapping>
If I access Home.jsp directly it will re-direct to the Login Page. However, once logged in, the user is moved to the Home.jsp page which allows the user to execute a query against the database. The home URL will look like
http://localhost:8084/LiveTrades/Home.jsp
But once they provide input, it will move to a new page displaying the results with url string like
http://localhost:8084/LiveTrades/Request?BIC=cat (assuming the user entered 'cat' for the input 'BIC' field).
If a user inputs this above url directly when not logged not, it will process fine, when it shouldnt. I know this is because my filter is only being invoked from the Home.jsp page. How can I get around this to prevent pages with Request* to be filtered?
Would it be easier to have another jsp page, say Results.jsp, and have the Servlet that processes the information from the database pass the data on to Results.jsp? Then I can simply add Results.jsp to the web.xml.
I managed to solve this problem by re-structuring my webpage. The results are now displayed via a JSP page, the data is passed to the JSP page from a Servlet. Now in my filter I simply add the Result JSP page and problem solved.
I have crated a portlet, Where I am doing my business logic in servlet. But I am getting the liferay login user details in the jsp page. So Now I need to pass the user details while hitting the servlet. This is my JSP code,
<%
String fullname= user.getFullName();
out.println("Full name is: "+fullname+ "...");
long id = themeDisplay.getLayout().getGroupId();
out.println("Site ID is: "+id+ "...");
long userId = themeDisplay.getUserId();
out.println("User ID is: "+userId+ "...");
%>
I need to access the above details in the servlet. How can I do that? Each login user has some different credentials, So all the values should update in and need to access in the servlet. what is the best way to access these values without performing any event. I am hitting the servlet from another web service. I need to access in Get OR Post method,
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
//I need to access those login user information here..
}
This will be really hard to do ("really hard" as in "almost impossible"): When you're in a servlet, all the portal's code of identifying the actual user won't run.
In fact, when you look at the HttpServletRequest for a portlet: This will be directed towards the portal and only later be forwarded to the portlet, with the properly constructed context (e.g. logged in user).
When you look at the servlet, this will be directed to your servlet. Your servlet typically lives in a totally different application context. Thus - by servlet specification - it will be totally separated from the portal environment.
Everything that you find to mitigate this limitation will be somewhat of a hack. Some people use cookies or request parameters. But they all are introducing more or less problems. Especially when you speak of webservices that access your servlet, you can't go with cookies.
In the interest of a well maintainable implementation, my recommendation is to change your architecture. Unfortunately you don't give enough context to recommend what to change your architecture to.
I am building a simple WebApplication using servlets. I am a beginner but have tried to learn the most of this technology. There is something I cannot figure out. One of my servlets is the useful BalusC FileServlet
http://balusc.blogspot.mx/2007/07/fileservlet.html
It responds to GET requests with the required file, nice and clean.
I use this FileServlet to serve CSV files for a Dygraph
http://dygraphs.com/
I have two types of users: guests and admins. Guests should be able to SEE the graph BUT NOT be able to DOWNLOAD the CSV file. Admins should be able to do both.
The fileServlet responds to URL-patterns as: file/* (* is the filename), and it is VERY convenient as the Dygraph reads for a file as specified in an URL.
There is a loginServlet built within this webapp, and I want to be able to avoid the fileservlet to GIVE the file if the user just copy-pastes the URL that is given for the Dygraph. The FileServlet is already capable of getting the session and loggeduser from that session, but I don't know how to detect what was the page that called the GET method. I want the fileservlet to serve the file ONLY when called from within the JSP code, and not from the browser's address bar.
Let me explain a bit:
I mean -as a guest user- the following Javascript code should display the graph (the FileServlet serves the file)
<div id="graphdiv2" style="width:640px; height:480px;">
<script type="text/javascript">
g2 = new Dygraph(
document.getElementById("graphdiv2"),
"${messages.rutacsv}", // path to CSV file
{
rollPeriod: 10,
showRoller: true
}
);
</script>
</div>
The variable:
"${messages.rutacsv}" gets replaced by the servlet for something that looks like this:
"file/2012-04-20_1.csv"
So the Dygraph loads the file nicely and plots the lines.
BUT, I want the FileServlet to be able to detect when the user copypastes this URL after the ContextName and block it, so only the Dygraph can download the file.
For example, if the user types in his browser:
http://localhost:8080/MyWebApp/file/2012-04-20_1.csv
It shouldn't be able to download it. Only admins should be able to.
NOW, I am thinking that maybe I should implement the FileServlet so it has to be called with another URL pattern or with a POST method so a simple user copy-pasta can't get past the "origining-JSP" check.
BTW, I'm coming back from trying with Struts2, which is by far too complicated for this application. I abandoned it for convenience and ease of development with simple servlets and JSPs.
Use a filter to check a user role. That's, before the any important action is necessary to check whether the user has a right to this action. This is the task servlet filter.
You must implement the method doFilter() in your class extending javax.servlet.Filter as follows:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
String currentRole = (String) session.getAttribute("userRole");
if ("admin".equals(currentRole)) {
successRedirect();
} else {
failRedirect();
}
chain.doFilter(request, response);
}
And don't forget map this filter to the needed address in the web.xml file:
<filter>
<filter-name>CheckRightAccessFilter</filter-name>
<filter-class>yourproject.CheckRightAccessFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CheckRightAccessFilter</filter-name>
<url-pattern>*.csv</url-pattern>
</filter-mapping>
Use servlet filter who check the submiited url and on the basis of the session object it identifies the user role. If it finds the authorized user then it can redirct to the download page
I build a custom AuthenticationSuccessHandler so users can login using Ajax aswell use a normal login (for users with javascript disabled). To check if it's an ajax call or normal call I sent an extra request header.
If it is an Ajax call i want to return some different code as on normal request. This results needs to come from a jsp file. I could sent the url back but than the user have to do another request to get the data. How can i read the output of the jsp file from within my code or is this a bad design?
This is how i handle the request.
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication auth) throws IOException,
ServletException{
if ("true".equals(request.getHeader("X-Ajax-call"))) {
response.getWriter().print("Output of jsp file should go here?");
response.getWriter().flush();
} else {
defaultHandler.onAuthenticationSuccess(request, response, auth);
}
}
Can't you simply forward the request:
request.getRequestDispatcher("myFile.jsp").forward(request, repsponse);