I have web application with spring, spring security, spring session with hazelcast.
It is running on clustered environment.
I see this exception in logs from time to time but can't reproduce it in locally.
It looks like some itercetptor or filter does not work correctly.
Any suggestion how to find the cause of the problem?
java.lang.IllegalStateException: Cannot forward after response has been committed
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:328) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318) [catalina.jar:8.0.35]
at org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler.handleRequest(DefaultServletHttpRequestHandler.java:122) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:720) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:584) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:523) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:436) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:379) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:176) [catalina.jar:8.0.35]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.35]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.35]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) [catalina.jar:8.0.35]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) [tomcat-coyote.jar:8.0.35]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-coyote.jar:8.0.35]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) [tomcat-coyote.jar:8.0.35]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) [tomcat-coyote.jar:8.0.35]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.35]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>xxxx</display-name>
<description>xxxx</description>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class>
</listener>
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.xxxxx.services.authentication.xxxxApplicationContextInitializer</param-value>
</context-param>
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>LoggerContextFilter</filter-name>
<filter-class>ch.qos.logback.classic.selector.servlet.LoggerContextFilter</filter-class>
</filter>
<filter>
<filter-name>PageExpiryFilter</filter-name>
<filter-class>com.xxxxx.web.filters.PageExpiryFilter</filter-class>
</filter>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter>
<filter-name>HttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter>
<filter-name>sessionIpAddressSecurityFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>LoggerContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>PageExpiryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>HttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sessionIpAddressSecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>yyyy</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>yyyy</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error-page</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/resourceNotFound</location>
</error-page>
<error-page>
<error-code>405</error-code>
<location>/resourceNotFound</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/resourceNotFound</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/notAuthorized</location>
</error-page>
<error-page>
<error-code>401</error-code>
<location>/notAuthorized</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/serverError</location>
</error-page>
<error-page>
<error-code>503</error-code>
<location>/serverError</location>
</error-page>
<error-page>
<error-code>504</error-code>
<location>/serverError</location>
</error-page>
<jsp-config>
<taglib>
<taglib-uri>http://xx.xx.xxx.com/tlds/functions</taglib-uri>
<taglib-location>/WEB-INF/tags/review.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
PageExpiryFilter:
public class PageExpiryFilter implements javax.servlet.Filter {
private static final int HOUR_TO_MINUTE = 60;
private static final int DAY_TO_MINUTE = 60 * 24;
private static final int MONTH_TO_MINUTE = 60 * 24 * 30;
private static final int WEEK_TO_MINUTE = 60 * 24 * 7;
private PageExpiryFilterPropertiesLoader loader = new PageExpiryFilterPropertiesLoader();
private final Pattern pattern = Pattern.compile("^(\\d+)(m|M|h|d|w)$");
private final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
private Map<String, Integer> pathRegex;
#Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
if (response instanceof HttpServletResponse && request instanceof HttpServletRequest) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final String path = httpServletRequest.getRequestURI();
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
setResponseHeader(path, httpServletResponse);
}
chain.doFilter(request, response);
}
private void setResponseHeader(final String path, final HttpServletResponse httpServletResponse) {
String expiryDate;
for (final String regex : pathRegex.keySet()) {
if (path.matches(regex)) {
final Integer age = pathRegex.get(regex);
expiryDate = createExpiryDate(age);
httpServletResponse.setHeader("Expires", expiryDate);
}
}
}
private String createExpiryDate(final Integer age) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, age);
return dateFormat.format(calendar.getTime());
}
#Override
public void init(final FilterConfig filterConfig) throws ServletException {
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
pathRegex = new LinkedHashMap<String, Integer>();
Properties properties = loader.loadProperties("/expires.properties");
populatePathRegex(properties);
}
private void populatePathRegex(final Properties properties) {
for (Entry<Object, Object> property : properties.entrySet()) {
Integer expirationInMinutes = getExpirationInMinutes(((String) property.getValue()).trim());
pathRegex.put((String) property.getKey(), expirationInMinutes);
}
}
private Integer getExpirationInMinutes(final String value) {
Integer minutes = 0;
if (value != null && value.length() != 0) {
final Matcher matcher = pattern.matcher(value);
if (matcher.matches()) {
final int val = Integer.parseInt(matcher.group(1));
final String denomination = matcher.group(2);
minutes = calculateMinutes(val, denomination);
} else {
throw new IllegalArgumentException("Invalid pattern '" + value + "'" + " for '" + value
+ "'. Valid patterns are '2m' for 2 minutes, '10h' for 10 hours, '1d' for 1 day, '1w' for 1 week, '1M' for 1 month");
}
}
return minutes;
}
private Integer calculateMinutes(final int val, final String denomination) {
int factor;
if ("m".equals(denomination)) {
factor = 1;
} else if ("h".equals(denomination)) {
factor = HOUR_TO_MINUTE;
} else if ("d".equals(denomination)) {
factor = DAY_TO_MINUTE;
} else if ("M".equals(denomination)) {
factor = MONTH_TO_MINUTE;
} else {
factor = WEEK_TO_MINUTE;
}
return val * factor;
}
public void setLoader(final PageExpiryFilterPropertiesLoader loader) {
this.loader = loader;
}
#Override
public void destroy() {
}
}
Related
while processing injection of spring security to my web app i get problem HTTP Status 404 error. When i try to get access for my pages first of all i get login page which is auto config, after typing login and password which is correct i get HTTP Status 404 error. Code below
web.xml
<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_2_5.xsd"
id="WebApp_ID" version="2.5">
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml, /WEB-INF/application-security.xml</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
application-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.1.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/main/**" access="hasRole('ROLE_USER')" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="adminpassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="user" password="userpassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
Controller
#Controller
#RequestMapping(value = "/main")
public class MainController {
#Autowired
DeputesAppealService deputesAppealService;
#Autowired
DeputesAppealDao deputesAppealDao;
#RequestMapping(value = "/mainFrame", method = RequestMethod.GET)
public String getMainPage(){
return "mainPage";
}
#RequestMapping(value = "/resultOfSearching", method = RequestMethod.GET)
public String getSearchResult(Model model, #ModelAttribute("searchChar")String searchResult) {
List<DeputesAppeal> deputesAppeals = deputesAppealService.abstractSearch(searchResult);
model.addAttribute("ListOfAppeals", deputesAppeals);
return "searchingResultPage";
}
#RequestMapping(value = "/new", method = RequestMethod.GET)
public String getAddNewAppealPage(){
return "addPage";
}
#RequestMapping(value = "/new", method = RequestMethod.POST)
public String addNewAppeal(#ModelAttribute("Appeal")DeputesAppeal deputesAppeal) {
deputesAppealService.add(deputesAppeal);
return "mainPage";
}
#RequestMapping(value = "/deleted", method = RequestMethod.GET)
public String deleteAppeal(#RequestParam(value = "id", required = true) Long id, Model model){
deputesAppealService.delete(id);
model.addAttribute("id", id);
return "deletedPage";
}
#RequestMapping(value = "/editPage", method = RequestMethod.GET)
public String GetEdit(#RequestParam(value = "id", required = true) Long id, Model model){
model.addAttribute("editedAppeal", deputesAppealService.getById(id));
return "editPage";
}
#RequestMapping(value = "/editPage", method = RequestMethod.POST)
public String editCurrentAppeal(#ModelAttribute("userAttribute") DeputesAppeal deputesAppeal,
#RequestParam(value = "id", required = true)Integer id, Model model) {
deputesAppeal.setNumber(id);
deputesAppealService.edit(deputesAppeal);
model.addAttribute("id", id);
return "editedPage";
}
}
Just see if you have springSecurityFilterChain defined in your web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
You also need to change Login URL as well
<c:url value="/j_spring_security_check" var="loginUrl" />
and use this in your form action:
<form action="${loginUrl}" method="post">
I'm working with Java, Jetty and Jersey 2.18 (latest for now) hosted on a Google App Engine.
Let say I have a service such that
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/{userId}")
public Response getUser(#PathParam("userId") String userId)
{
...
}
When I do:
return Response.ok()
.entity(user)
.build();
I correctly receive an application/json content-type and body.
But when I do:
return Response
.status(404)
.entity(new ResponseModel(100, "user not found"))
.build();
same as for returning any 4XX or 5XX status, I receive a text/html content-type along with this HTML body:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>404 Not Found</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Not Found</h1>
</body>
</html>
and not the object I put in .entity()
Edit: Here is my web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.mypackage.services;org.codehaus.jackson.jaxrs</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
org.glassfish.jersey.server.gae.GaeFeature;
org.glassfish.jersey.server.mvc.jsp.JspMvcFeature;
org.glassfish.jersey.media.multipart.MultiPartFeature;
</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.Trace</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattytern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>home.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring Security Filter -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml </param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>GlobalResponseFilter</filter-name>
<filter-class>com.mypackage.GlobalResponseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>GlobalResponseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>everything</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<!-- ** -->
<!-- ** General session timeout in minutes -->
<!-- ** -->
<session-config>
<session-timeout>1440</session-timeout>
</session-config>
</web-app>
ResponseModel is just a basic serializable java class :
import java.io.Serializable;
public class ResponseModel implements Serializable
{
private static final long serialVersionUID = 1L;
private int code;
private Serializable data;
public ResponseModel()
{
}
public ResponseModel(int code, Serializable data)
{
System.err.println("Code " + code + " : " + data);
this.code = code;
this.data = data;
}
public int getCode()
{
return code;
}
public void setCode(int code)
{
this.code = code;
}
public Serializable getData()
{
return data;
}
public void setData(Serializable data)
{
this.data = data;
}
}
Can you try again with the following configuration:
<servlet>
<servlet-name>API</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
...
<init-param>
<param-name>jersey.config.server.response.setStatusOverSendError</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
This flag defines if Jersey - when sending a 4xx or 5xx response status - uses ServletResponse.sendError(flag is false) or ServletResponse.setStatus (flag is true).
Calling ServletResponse.sendError usually resets the response entity and headers and returns a (text/html) error page for the status code.
Since you want to return an own custom error entity, you need to set this flag to true.
Stripes ActionBeanContext is returning null on all pages where I try to call it.
Here's my shortened ActionBean code:
package stripesbook.action;
public class InitialInfoActionBean implements ActionBean {
private ActionBeanContext context;
public void setContext(ActionBeanContext Context) {
this.context = Context;
}
public ActionBeanContext getContext() {
return this.context;
}
#DefaultHandler
public Resolution nextPage() throws Exception {
return new ForwardResolution("/estimate-info.jsp").addParameter("id", id);
}
}
Here's my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<description>Perceptive Calculator</description>
<display-name>Perceptive Calculator</display-name>
<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
<init-param>
<param-name>ActionResolver.Packages</param-name>
<param-value>stripesbook.action</param-value>
</init-param>
<init-param>
<param-name>ActionBeanContext.Class</param-name>
<param-value>stripesbook.action.PerceptiveActionBeanContext</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<servlet-name>StripesDispatcher</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>StripesDispatcher</servlet-name>
<servlet-class>net.sourceforge.stripes.controller.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StripesDispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
I'm not doing anything on my .jsp page except setting the bean with <jsp:useBean id="actionBean" class="stripesbook.action.InitialInfoActionBean" /> and checking for null context with ${ actionBean.context == null }
When posting back to the ActionBean, I'm able to perform various operations but in most cases, setContext never even gets hit.
Figured this out. Instead of
<jsp:useBean id="actionBean" class="stripesbook.action.InitialInfoActionBean" />`
I needed to be using
<stripes:useActionBean beanclass="stripesbook.action.InitialInfoActionBean" executeResolution="false" event="populate" var="actionBean" />
Apparently the regular useBean tag doesn't populate the context.
In my application we have implemented several filters. For example I have three filters
Locale Filter
License Filter
Login Filter
The order is working fine in normal case. But when I am giving continuous refresh it sometimes skips the License Filter (execution then is: Locale Filter -> Login Filter).
Is there any way to avoid this? The order should not change even when I continuously refresh. The order should be followed every time.
public class LicenseFilter implements Filter {
#Override
public void destroy() {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
try {
LOGGER.info("In LicenseFilter");
licenseValidator.validate();
chain.doFilter(req, res);
}catch (Exception excep) {
LOGGER.error("License Error " + excep.getMessage());
req.setAttribute("error", excep.getMessage());
RequestDispatcher dispatcher = req
.getRequestDispatcher("license_list.action");
dispatcher.forward(req, res);
}
}
}
#Override
public void init(FilterConfig cfg) throws ServletException {
WebApplicationContext wctx = WebApplicationContextUtils.getWebApplicationContext(cfg
.getServletContext());
licenseValidator = (licenseValidator) wctx.getBean("licenseValidator");
ctx = cfg.getServletContext().getContextPath();
}
}
web.xml
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>web</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>META-INF/beans-*.xml</param-value>
</context-param>
<filter>
<filter-name>localeFilter </filter-name>
<filter-class>com.filter.LocaleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>localeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>licenseFilter</filter-name>
<filter-class>com.filter.licenseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>licenseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
I have a problem for mapping my servlet with my Java Server Page, using the JSF framework and especially the commandLink tag.
When I click on the commandLink it only reload the same productList.jsp.
Here is my map web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Epimarket</display-name>
<servlet>
<servlet-name>mainServlet</servlet-name>
<servlet-class>com.epimarket.controller.EpimarketServlet</servlet-class>
<init-param>
<param-name>listURL</param-name>
<param-value>productList.jsp</param-value>
</init-param>
<init-param>
<param-name>editURL</param-name>
<param-value>productEdit.jsp</param-value>
</init-param>
<init-param>
<param-name>errorsURL</param-name>
<param-value>errors.jsp</param-value>
</init-param>
</servlet>
<filter>
<filter-name>MyFacesExtensionsFilter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
<init-param>
<param-name>maxFileSize</param-name>
<param-value>20m</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.PRETTY_HTML</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
<param-value>true</param-value>
</context-param>
<servlet-mapping>
<servlet-name>mainServlet</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Here is the faces-config.xml
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<application>
<locale-config>
<default-locale>fr</default-locale>
</locale-config>
</application>
<navigation-rule>
<from-view-id>/*</from-view-id>
<navigation-case>
<from-outcome>productList</from-outcome>
<to-view-id>/productList.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>productEdit</from-outcome>
<to-view-id>/productEdit.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>chart</from-outcome>
<to-view-id>/chart.jsp</to-view-id>
</navigation-case>
</navigation-rule>
Here is my link to create a new Product (access editProduct.jsp page)
<h:commandLink id="createProductLink" value="Ajouter un produit" action="/do/edit"/>
Prefix h is for
<%# taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
And finally my doGet and doEditProduct methods in my Servlet :
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException
{
if (initErrors.size() != 0)
{
req.setAttribute("erreurs", initErrors);
getServletContext().getRequestDispatcher(urlErrors).forward(req, res);
return ;
}
String reqType = req.getMethod().toLowerCase();
String action = req.getPathInfo();
if (action == null)
action = "/list";
if (reqType.equals("get") && action.equals("/list"))
{
doProductList(req, res);
return ;
}
if (reqType.equals("get") && action.equals("/delete"))
{
doDeleteProduct(req, res);
return ;
}
if (reqType.equals("get") && action.equals("/edit"))
{
doEditProduct(req, res);
return ;
}
if (reqType.equals("post") && action.equals("/validate"))
{
doValidateProduct(req, res);
return ;
}
doProductList(req, res);
}
private void doEditProduct(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException
{
int id = Integer.parseInt(req.getParameter("id"));
Product product = null;
if (id != -1)
product = service.getProduct(id);
else
{
product = new Product();
product.setId(new BigDecimal(-1));
}
req.setAttribute("editError", "");
req.setAttribute("id", product.getId());
req.setAttribute("name", product.getName());
req.setAttribute("description", product.getDescription());
req.setAttribute("price", product.getPrice());
getServletContext().getRequestDispatcher((String)params.get("editURL")).forward(req, res);
}
Thank you for your help
With JSF you must not used servlets. You use managed beans.
In order to fix the above code, you should provide an action method, and invoke that method from your command button. In order to get more into the spirit of JSF, I'd suggest starting with a tutorial and/or a sample JSF probject.