I'm using form based authentication.
I have a logout link which looks like:
<h:commandLink action="#{loginBean.logout}">
<h:outputText value="logout" />
</h:commandLink></div>
And the corresponding logout method:
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "/view/index?faces-redirect=true"; // Redirect added as per BalusC's suggestion.
}
After hitting the logout link I'm returned to the front page, but seemingly without CSS. When I hit a button to run a search I get the following error:
javax.faces.application.ViewExpiredException: viewId:/view/index.jsf - View /view/index.jsf could not be restored.
And yet the CSS is actually under /resources which shouldn't require authentication as I understand my web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>fizio</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Unprotected area</web-resource-name>
<url-pattern>/resources/*</url-pattern>
</web-resource-collection>
</security-constraint>
From this state I seem to be able to login again and see some data between occasional view-could-not-be-restored errors, but no CSS. It's all a bit broken really. Any suggestions would be appreciated.
ETA: Login form:
<form method="POST" action="j_security_check">
<label for="j_password">Username:</label> <input type="text" name="j_username" />
<br />
<label for="j_password">Password:</label> <input type="password" name="j_password" /> <input type="submit" value="Login" />
</form>
You need to redirect after invalidate. Otherwise the page is been shown in midst of the "invalidated" session. Add faces-redirect=true to the outcome to trigger the redirect.
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "/index?faces-redirect=true";
}
The redirect will cause the webbrowser to fire a new GET request after the POST response and in turn cause the server to create a brand new session. This way the views will work as intended.
As to the CSS resources, they apparently still need a login. The "Unprotected area" constraint which you have there is not going to work. Remove it and change the URL-pattern of your main security constraint to for example /app/* or whatever a common path of the secured area is.
Related
I want to create a simple JSP/Servlet login page that authenticate using websphere ldap repository.
All examples I've found looks very complex, with hundreds of lines of code just to authenticate.
Is this really so complex?
Does anyone have a simple example or article that explains how to authenticate a user/pass against a ldap repository already configured as websphere federated repository?
I really appreciate any help.
Thanks
This is quit simple in reality. You need following pieces:
1) Login page with form that points to j_security_check
See this page for details Customizing web application login
Very simplified example is like this:
<form method="POST" action="j_security_check">
<input type="text" name="j_username">
<input type="text" name="j_password" autocomplete="off">
<\form>
2) Security configured in web.xml
Something like this:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login.jsp</form-error-page>
</form-login-config>
</login-config>
plus security constraint:
<security-constraint>
<display-name>allResources</display-name>
<web-resource-collection>
<web-resource-name>allResources</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>users</role-name>
</auth-constraint>
</security-constraint>
3) Application security enabled on the application server and user registry configured.
That's it.
This question already has answers here:
What causes "java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute"?
(7 answers)
Closed 6 years ago.
I am beginner to Spring MVC Framework. I started to learn Spring two days back. For learning purpose I am developing one simple Application. i.e., Get user input from form and display values in another page. I got an Exception " java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute". I cant figure out what's wrong in my code. I searched Google and tried many solution but the problem is still here.
Here is my view
index.jsp
<form:form action="/addDisplay" method="POST">
<form:label path="name"><h3>Name</h3></form:label>
<form:input type="text" path="name" cssClass="form-control text-center" required="required"/>
<form:label path="age"><h3>Age</h3></form:label>
<form:input type="number" path="age" cssClass="form-control text-center" required="required"/>
<form:label path="work"><h3>Work Place</h3></form:label>
<form:input type="text" path="work" cssClass="form-control text-center" required="required"/>
<form:label path="designation"><h3>Designation</h3></form:label>
<form:input type="text" path="designation" cssClass="form-control text-center" required="required"/>
<form:label path="area"><h3>Area</h3></form:label>
<form:input type="text" path="area" placeholder="Where Are You From?" cssClass="form-control text-center" required="required"/>
<form:label path="mobile"><h3>Mobile Number</h3></form:label>
<form:input type="number" path="mobile" placeholder="Your Mobile Number.!" cssClass="form-control text-center" required="required"/>
<form:label path="email"><h3>Email</h3></form:label>
<form:input type="email" path="email" placeholder="Your Email Id..!" cssClass="form-control text-center" required="required"/>
<br/>
<input type="submit" value="Generate" class="btn btn-success form-control"/>
</form:form>
myself.jsp
<div style="margin-top: 3%; font-size: 20px;">
<h3>My Introduction.</h3>
<p>
Hi, I am ${name} my age is ${age} and I am from ${area}. I am working as a ${designation}
in ${work}. You can contact me in my mobile ${mobile} and You can also shoot mail to
${email}.
</p>
</div>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SpringWork</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
mvc-dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.infofaces.spring.form" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="com/infofaces/spring/form/MySelf" />
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
</beans>
My model name is Myself.java and it has private variables and getter, setter methods for that variable. Here is my controller.
HelloController.java
package com.infofaces.spring.form;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class HelloController {
#RequestMapping(value = "/display", method = RequestMethod.GET)
public ModelAndView display() {
return new ModelAndView("myself", "command", new MySelf());
}
#RequestMapping(value="/addDisplay", method = RequestMethod.POST)
public String addDisplay(#ModelAttribute("command") MySelf myself, ModelMap model) {
model.addAttribute("name",myself.getName());
model.addAttribute("age", myself.getAge());
model.addAttribute("work", myself.getWork());
model.addAttribute("designation", myself.getDesignation());
model.addAttribute("mobile", myself.getMobile());
model.addAttribute("email", myself.getEmail());
return "myself";
}
}
Full Stack Trace.
type Exception report
message java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:465)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:179)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:199)
org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:130)
org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:120)
org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:90)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:103)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
org.apache.jsp.index_jsp._jspx_meth_form_005flabel_005f0(index_jsp.java:265)
org.apache.jsp.index_jsp._jspx_meth_form_005fform_005f0(index_jsp.java:170)
org.apache.jsp.index_jsp._jspService(index_jsp.java:105)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Please help to find problem in my code. Thanks in advance.
You are missing commandName="command" in your index.jsp file .
<form:form action="/addDisplay" method="POST" commandName="command" >
Make sure that command object is available in your request attribute before index.jsp is being processed. I hope this would work.
EDIT : As you said in comment when you call index.jsp definatily you will get java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute error.
Because when your jsp is being rendered command object not available for that first you have to make request to controller , put object into Model name it command and then provide view name index.jsp
For example :
#RequestMapping(value = "/index", method = RequestMethod.GET)
public ModelAndView display() {
return new ModelAndView("index", "command", new MySelf());
}
Now you won't get that error. I hope this would work.
Instead of forwarding to your index.jsp via welcome-files list, you should add
<mvc:view-controller path="/" view-name="index"/>
to your mvc configuration, and an accompanying controller mapping where you will add the command object to the model, e.g.
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model model) {
model.addAttribute("command", new MySelf());
return "index";
}
Your problem is that you got forwarded to the index.jsp via welcome-files and the request wasn't process by spring. Yet you use spring's form:form which if not otherwise renamed via commandName or modelAttribute attributes expects an object with the key command inside the request attributes
you have used spring form tag in index.jsp where a command/modelAttribute object should be available as a request parameter to bind form data, which is you have not done and the exception message what it says.
To solve this problem follow below steps:
Step 1:
Remove all welcome-file-list from web.xml.
Step 2:
add "/" into display GET handler.
#RequestMapping(value = {"/", "/display"}, method = RequestMethod.GET)
public ModelAndView display() {
return new ModelAndView("myself", "command", new MySelf());
}
Step 3:
add modelAttribute name in form tag:
<form:form action="${pageContext.request.contextPath}/addDisplay"
method="POST"
modelAttribute="command">
Consider, you have HTML form like below
Login Form:
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<body>
<form:form action="doLogin.html" method="post" modelAttribute="loginEntity" name="loginForm">
<!-- Form inputs -->
</form:form>
</body>
</html>
You want to perform login by calling action doLogin.html. As you have specified modelAttribute="loginEntity" attribute in Spring form which is created using above code snippet. You must set an empty Object of model which hold required request params in Controller. Observe below code carefully:-
Model Class:
public class Login {
private String userName = "";
private String password = "";
// getters/setters
}
Controller Class:
#Controller
public class LoginController {
#RequestMapping(value = "/showLoginForm", method = RequestMethod.GET)
public ModelAndView showLoginForm() {
System.out.println("In login form...");
ModelAndView mv = new ModelAndView("login");
mv.addObject("loginEntity", new Login());
return mv;
}
#RequestMapping(value = "/doLogin", method = RequestMethod.POST)
public ModelAndView doLogin(#ModelAttribute Login login, BindingResult result) {
String userName = login.getUserName();
String password = login.getPassword();
if ("OO7".equals(userName) && "OO7".equals(password)) {
return new ModelAndView("forward:success.html");
} else {
return new ModelAndView("forward:failure.html");
}
}
}
In the controller, I have added an empty model new Login() for the modelAttribute loginEntity in the showLoginForm() function. This will map all the request parameters & allow to set &/or retrieve values from them.
Now, you can add link to your index.jsp which will give a call to Controller to display login.jsp just like below :-
Index Page:
<html>
<body>
<ul>
<li>Login</li>
</ul>
</body>
</html>
Overall Request Flow:
At application start index.jsp will load having a link to login.jsp.
On click of link Login a call to controller is made & it searches for request mapping showLoginForm in it.
Once he found the specified mapping, he proceed further to display login.jsp page.
On submit of the login form, a request for doLogin.html is made. Once again control goes to Controller to search for doLogin request mapping.
Once he found doLogin request mapping, depending on the login credentials, you will be redirected to either success.jsp or failure.jsp page.
NOTE:
Don't mix commandName & modelAttribute in Spring form. You are only allow to use any of them.
If you forgot to add empty model in the Controller, then you will face below exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for
bean name 'loginEntity' available as request attribute
I hope this will clear your idea of using #ModelAttribute in Spring.
I'm new to IT industry. Test scenario is like I need to test whether my application's login page is SSL secured or not?
In general sometime we used to visit some websites where it shows a pop-up for SSL security. So I need to test the same scenario in my application.
I have small web application where I have login.html page. Basically, I'm able to start my web application using Maven and server used is Tomcat. Command I'm using to start is mvn tomcat7:run and URL using http://localhost:8080/login.html. It works perfectly.
But I want to change my URL from http to https and when I access my URL, i.e to https://localhost:8080/login.html, then it should pop-up with SSL security alert and I should accept it.
If my question is still not clear then feel free to comment.
After searching on net I have done some workarounds but its not working out. What I have tried:
My HTML page
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Login App</h1>
<div id="emptyDiv"></div>
<div id="description"></div>
<!--container start-->
<div id="container">
<div id="container_body" style="background-color:#BBD700;float:center;">
<!--Form start-->
<div id="form_name">
<div class="firstnameorlastname">
<form >
<div id="errorBox"></div>
First Name : <input id="firstName" type="text" name="Name" value="" >
Last name : <input id="lastName" type="text" name="LastName" value="" >
</div>
<div id="email_form">
Email Id: <input style="position:right" type="text" name="Email" value="" >
</div>
<input id="sub_form" type="submit" value="Submit">
</form>
</div>
<!--form ends-->
</div>
</div>
<!--container ends-->
</body>
</html>
web.xml
<pre><code><!DOCTYPE web-app PUBLIC <span style="color: red;">"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"</span> <span style="color: red;">"http://java.sun.com/dtd/web-app_2_3.dtd"</span>>
<web-app>
<!-- <security-constraint>
<web-resource-collection>
<web-resource-name>MyEducationApp</web-resource-name>
<url-pattern>/login.html</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Non-SecureResource</web-resource-name>
<url-pattern>/login.html</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint> -->
<display-name>Login WebApp</display-name>
</web-app>
</span></code></pre>
Maven Plugin used
<!-- Maven Tomcat Plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>https://localhost:8080/manager/text</url>
<server>localhost</server>
<path>/</path>
<username>admin</username>
<password>aRfalah</password>
</configuration>
<executions>
<execution>
<id>tomcat7-run</id>
<goals>
<goal>run-war-only</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<fork>true</fork>
</configuration>
</execution>
<execution>
<id>tomcat7-shutdown</id>
<goals>
<goal>shutdown</goal>
</goals>
<phase>post-integration-test</phase>
</execution>
</executions>
</plugin>
SSL/TLS encryption for your web site is nothing you can do in your web application. It's done via your web server's configuration.
See Apache Tomcat 7, SSL Configuration HOW-TO.
Additional info (repeated from my comment to the OQ, since comments are not that prominent and editable):
You don't have to buy a certificate from one of the certification authorities (CA) to obtain a certificate.
StartSSL offers 1-year SSL/TLS + S/MIME for free. On a different domain they offer now:
No offer any more:
Notice to all StartCom subscribers
StartCom CA is closed since Jan. 1st, 2018 that don’t issue any new certificate from StartCom name roots.
If you want to buy trusted SSL certificate and code signing certificate, please visit https://store.wotrus.com.
If you want to apply free email certificate, please visit https://www.mesince.com to download MeSince APP to get free email certificate automatically and send encrypted email automatically.
But there may be other companies meanwhile.
You can easily create your own certificates with OpenSSL (thus being your own CA) and associate this certificate with your https:// site. If your visitors accept your certificate in the dialog that pops up in their browser it is stored in their browser's certificate store and the dialog will not appear again until the certificate's expiration date is reached.
This is what you need to do:
Generate a self signed certificate and install the same in Tomcat (Gerold Broser's post has the link)
By default, the SSL port is disabled in Tomcat, enable it (same link as bove)
Change your URL to https://local_host:8443/login.html (default SSL port for Tomcat)
Make the request through your browser, you should see a page/message, depending on the browser, telling you that the certificate is not OK
If you want this page to be only accessed through SSL, look at Tim Funk's post and edit the web.xml of the application.
The normal practice is to check via request.isSecure() whether the request came in via https or not. If not then send a redirect to the browser to the same URL but prefixed with https protocol.
Here is an example servlet filter to do this:
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SecurityFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse servletResponse = (HttpServletResponse) response;
if (!request.isSecure()) {
HttpServletRequest servletRequest = (HttpServletRequest) request;
String target = "https://" + request.getLocalName() + servletRequest.getRequestURI();
servletResponse.sendRedirect(target);
return;
}
// tell the browser to use only https for accessing this domain for the next 30 days
servletResponse.addHeader("Strict-Transport-Security", "max-age=" + (30 * 24 * 60 * 60));
chain.doFilter(request, response);
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
// not needed
}
#Override
public void destroy() {
// not needed
}
}
To enable the filter globally add the following to you web.xml:
<filter>
<filter-name>securityFilter</filter-name>
<filter-class>SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The line servletResponse.addHeader("Strict-Transport-Security", ... is optional. If you put it into the code, your browser will never try to connect to http again for the next 30 days but will use https itself. That happens if your browser supports the HSTS standard RFC6797. That makes sense if your application should be accessible via https solely. However, I think it is only possible with the standard https port 443. See next.
There is a tiny pitfall in your current tomcat configuration. It is not possible to run http and https on the same port. You need to have two separate connectors one for http and one for https.
To make this happen add to the maven tomcat plugin configuration:
<!-- Maven Tomcat Plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<httpsPort>8443</httpsPort>
. . .
You also need to add the correct protocol for the redirect target in the SecurityFilter code (or make it an parameter):
String target = "https://" + request.getLocalName() + ":8443" + servletRequest.getRequestURI();
The port 8080 and 8443 are only for experimental local web servers, real applications should be on port 80 and 443.
That's it. Have fun and good luck!
To require HTTPS and have your servlet engine automatically redirect to https, you are on the right track with transport-guarantee
So you will probably want
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Context</web-resource-name>
<url-pattern>/login.html</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
The above will only redirect /login.html for your webapp to https. Add more url-pattern as needed.
More details:
http://wiki.apache.org/tomcat/FAQ/Security#Q4 and
http://marc.info/?l=tomcat-user&m=104951559722619&w=2
From the original question above:
Command I'm using to start is mvn tomcat7:run and URL using
http://localhost:8080/login.html. It works perfectly. But i want to
change my URL from http to https and when I access my URL i.e
https://localhost:8080/login.html
Are you sure about 'http://localhost:8080' and 'https://localhost:8080'?
This basically means that you are requesting both SSL and non SSL traffic from same port. Normally Tomcat does HTTP from 8080 and HTTPS from 8443.
Most of the answers here would work for you but first be sure to see if you have enabled the SSL connector in server.xml.
How can I call a specific method in a class using this tag?
<jsp:useBean id="user" scope="??" class="com.example.User" type="com.example.User" />
Assuming your bean User has a method called getName()
<jsp:useBean id="user" scope="request" class="com.example.User" />
// ...
<h1>Hello <jsp:getProperty name="user" property="name" /></h1>
The scope could be something else than request : depends on what you want (session, page, etc)
EDIT: your second question was about calling a business method in your jsp
The fact is, you should not call business method into your JSPs. Your JSP pages should only display static (html, etc) and dynamic (beans for example) content. If you follow MVC pattern, business job is delegated to servlets. Your JSPs are only simple views (reading properties of beans) and are forbidden (in directory WEB-INF).
For your JSP pages, proceed as following:
Action of html form is your servlet controller (method POST)
Add hidden input to help servlet recognize what to do: <input
type="hidden" name="action" value="update" /> or <input
type="hidden" name="action" value="register" />
You can also display dynamic content (beans). For that, you should consider using JSTL.
Example (servlet sends an ArrayList of Movie beans on request scope):
<c:forEach items="${requestScope.results}" var="movie">
// ${movie.title}
// etc
</c:forEach>
For your servlet controller, proceed as following:
In doPost method (because we're using POST method in html form), you can dispatch business logic depending on action received: request.getParameter("action")
If action is update, then we perform update business logic.
If action is register, then we perform register business logic.
etc ...
Now, we can store some data in request scope to communicate to jsp page:
ArrayList<Movie> results = new ArrayList<Movie>();
results.add(new Movie(...));
// etc...
request.setAttribute("results", results);
And finally, send data and display jsp:
request.getRequestDispatcher("/WEB-INF/update.jsp").forward(request, response);
An example of web.xml (with a servlet mapped as welcome file index.jsp)
<servlet>
<servlet-name>Search</servlet-name>
<servlet-class>Servlets.Search</servlet-class>
</servlet>
<servlet>
<servlet-name>Register</servlet-name>
<servlet-class>Servlets.Register</servlet-class>
</servlet>
<servlet>
<servlet-name>Update</servlet-name>
<servlet-class>Servlets.Update</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Search</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Register</servlet-name>
<url-pattern>/Register.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Update</servlet-name>
<url-pattern>/Update.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp:useBean id="user" scope="request" class="com.example.User" type="com.example.User" />
<jsp:setProperty name="user" property="*" />
<c:set var="saveStatus" value="${user.save()}" />
I have set the realm setting in server.xml host section to something like this:
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost:3306/test" connectionName="test" connectionPassword="test"
userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles"
roleNameCol="user_role" />
Also in web.xml:
<security-role>
<role-name>ADMIN</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>critical</web-resource-name>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
And I have the databased set up. However when login.jsp is envoked, even I entered the right password I was redirected to error.jsp
I want to know if there is a way to find what's wrong during the process. Can I do it in Eclipse or any other hints that may solve the problem?
To get the debug information from the Realm authentication steps, follow this procedure.
When you define your Realm in the server.xml, add debug="9" to the definition (you can of course use a lower number for less detail).
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost:3306/test" connectionName="test" connectionPassword="test"
userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles"
roleNameCol="user_role" debug="9" />
You also need to add this to your logging.properties file:
org.apache.catalina.realm.level = ALL
org.apache.catalina.realm.useParentHandlers = true
org.apache.catalina.authenticator.level = ALL
org.apache.catalina.authenticator.useParentHandlers = true
You may also need to add this, to prevent bufferring of the logs. If you do, remember to remove it after you've finished debugging.
1catalina.org.apache.juli.FileHandler.bufferSize = -1
Now, the debug logs for the realms should end up in the catalina.out file.
For others finding this issue, I found the following worked for Tomcat 8.5.40:
java.util.logging.ConsoleHandler.level = ALL
org.apache.catalina.level = FINEST
org.apache.catalina.realm.JNDIRealm.level = FINEST
org.apache.catalina.realm.JNDIRealm.useParentHandlers = true
The key fact appears to be that your logging travels through several layers of definitions and will be trimmed by the first one that has a lower level so you need to make sure that each bit it passes through is FINEST or ALL.
Hopefully this will save someone some time ;)
Ian.