Spring Security with custom login form not working - spring

I have a custom login form with spring security and when logging in I keep getting a 404
Heres my web config
package coffee.web;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("/regular/index.html");
}
}
Heres my security config
package coffee.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("peter").password("peter").authorities("ROLE_USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**").hasRole("USER").antMatchers("/", "/**").permitAll()
.and().formLogin().loginPage("/regular/login.html").permitAll().defaultSuccessUrl("/admin/adminIndex.html").and().csrf().disable();
}
}
Heres my login html form
<head>
<link href="index.css" type="text/css" rel="stylesheet" />
<link href="adminIndex.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div id="page">
<div id="bar"></div>
<header>
<h1><img id="logo" src="resources/logo.png" width="300" height="75" /></h1>
</header>
<section id="main">
<div id="container">
<div id="loginDiv">
<form name="login" id="login" action="login" method="POST">
<div id="formDiv">
<label for="addUsername" class="title">Username</label>
<span id="validateUsername" class="error"></span>
<input class="input" type="text" id="addUsername" name="username" />
<br />
<label for="addPassword" class="title">Password</label>
<span id="validatePassword" class="error"></span>
<input class="input" type="text" id="addPassword" name="password" />
<br />
<button id="submit" name="submit" type="submit" class="submit">submit</button>
</div>
</form>
</div>
</div>
</section>
</div>
</body>
Even when I turn authorization off, and only authentication is on, i still get the 403 error code after logging in. Even though I could still go directly to admin.adminIndex.html directly and it works.. (with authorization off and only authentication on).
Okay, I updated my security code with ".and().csrf().disable();" and now I am getting a 404 not found error when i log in.

That happened to me too (or at least something similar).
Try to add .and().csrf().disable() after .defaultSuccessUrl("/admin/adminIndex.html") to your configure method.

Related

JAVA 7 JSF inputFile ERROR javax.servlet.ServletException: UT010016: Not a multi part request

First of all a greeting and thanks in advance.
The reason for my creating this thread is because of an error that it generates when trying to load a file with
what I want is to capture a file, regardless of its extension, send it to the controller and then convert it to bytearray to store it in a postgre sql database.
<div class="row">
<div class=" text-mini col-lg-12 col-md-6 col-xs-6">
<h:form enctype="multipart/form-data">
<h:panelGrid columns="2">
<h:outputLabel value="Cargar archivo" for="fileUpload" />
<h:inputFile value="#{fileUploadFormBean.fileUpload}" id="fileUpload" />
<h:commandButton value="Cargar"/>
</h:panelGrid>
</h:form>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<h:panelGrid rendered="#{not empty(fileUploadFormBean.fileUpload)}" columns="2" >
<h:outputText value="fileName:" />
<h:outputText value="#{fileUploadFormBean.fileUpload.submittedFileName}" />
<h:outputText value="contentType:" />
<h:outputText value="#{fileUploadFormBean.fileUpload.contentType}" />
<h:outputText value="size:" />
<h:outputText value="#{fileUploadFormBean.fileUpload.size}" />
</h:panelGrid>
</div>
</div>
package com.esmero.cl.mvno.ticketin.controller;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.servlet.http.Part;
#ManagedBean(name = "filecontroller")
#ViewScoped
public class UpLoadFileController implements Serializable{
private static final long serialVersionUID = 1L;
private Part fileUpload;
/**
* Creates a new instance of FileUploadFormBean
*/
public UpLoadFileController() {
}
public Part getFileUpload() {
return fileUpload;
}
public void setFileUpload(Part fileUpload) {
this.fileUpload = fileUpload;
}
}
enter image description here
enter image description here

Spring Security Facebook Oauth2 redirected too many times

I am trying to implement Oauth2 implementation for facebook in Spring security following the example mentioned in https://spring.io/guides/tutorials/spring-boot-oauth2/
As facebook now allows only secured application as Oauth2 client, I have made the same by implementing SSL certificate locally.
My Spring application class:
package com.example.demo;
import java.security.Principal;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#EnableOAuth2Sso
#SpringBootApplication
#RestController
public class SimpleApplication extends WebSecurityConfigurerAdapter {
#RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.antMatcher("/**")
.authorizeRequests().antMatchers("/", "/login**", "/webjars/**").permitAll()
.anyRequest().authenticated();
}
public static void main(String[] args) {
SpringApplication.run(SimpleApplication.class, args);
}
}
Application.yml:
server:
port: 8648
ssl:
key-store: classpath:mycert.p12
key-store-password: password
key-store-type: PKCS12
key-alias: myCertX
security:
oauth2:
client:
clientId: 169343663729045
clientSecret: ea31bd0eb13e9856097ed9d186a1276a
accessTokenUri: https://graph.facebook.com/oauth/access_token
userAuthorizationUri: https://www.facebook.com/dialog/oauth
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
resource:
userInfoUri: https://graph.facebook.com/me
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Demo</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width" />
<base href="/" />
<link rel="stylesheet" type="text/css"
href="/webjars/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript"
src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<h1>Demo</h1>
<div class="container"></div>
<div class="container unauthenticated">
With Facebook: click here
</div>
<div class="container authenticated" style="display: none">
Logged in as: <span id="user"></span>
</div>
<script type="text/javascript">
$.get("/user", function(data) {
$("#user").html(data.userAuthentication.details.name);
$(".unauthenticated").hide()
$(".authenticated").show()
});
</script>
</body>
</html>
When I boot the application the index.html page open and after clicking the link for facebook login, the facebook page opens, I enter the credentials then after facebook redirect, I get this error : www.facebook.com redirected you too many times.
I tried changing the URL but it's still the same response.
In my facebook application the Valid OAuth Redirect URIs is set to https://localhost:8648/login

Internationalization of placeholders in Spring

I can not find the way to internationalize the text inside a placeholder like I do with regular text. I would like to place my internationalization in:
input type="text" class="form-control" name="s" placeHolder="Search Hobbies"
with input type="text" class="form-control" name="s" placeHolder="ctrlpanel.search.placeholder"
ctrlpanel.search.placeholder=Search Hobbies
Right now, in my JSP I include the tag
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<c:set var="contextRoot" value="${pageContext.request.contextPath}" />
<c:url var="search" value="/search" />
<hr/>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="${search}" method="post">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
<div class="input-group input-group-lg">
<input type="text" class="form-control" name="s" placeHolder="Search Hobbies">
<span class="input-group-btn">
<button id="search-button" class="btn btn-primary" type="submit">
<spring:message code="ctrlpanel.find.button" text="default text" />
</button>
</span>
</div>
</form>
</div>
</div>
My configuration works fine:
package com.caveofprogramming.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
#Configuration
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public LocaleResolver localeResolver(){
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(new Locale("es", "ES"));
//sessionLocaleResolver.setDefaultLocale(Locale.US);
return sessionLocaleResolver;
}
#Bean
LocaleChangeInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
#Override
public void addInterceptors(InterceptorRegistry interceptorRegistry){
interceptorRegistry.addInterceptor(localeChangeInterceptor());
}
}
Since this does not work.
<input type="text" class="form-control" name="s" placeHolder="<spring:message code="ctrlpanel.search.placeholder"/>">
Use var attribute of spring:message which is used when binding the result to the page, request, session or application scope.
<spring:message code="ctrlpanel.search.placeholder" var="searchPlaceholder"/>
And then update your input field like this:
<input type="text" class="form-control" name="s" placeHolder="${searchPlaceholder}">

Spring security: New user workflow

I am new to Spring security.
I have created a custom form that logs a user in and then, upon successful login, the user continues to his/her intended webpage. My implementation is standard and it works.
Here's my problem.
A user wants to go to page mywebpage.html.
The user is not logged in. The
user is redirected (by Spring Security) to the login page.
The user
does not have an account.
The user clicks on the createAccount link
and goes via standard MVC protocols to a registration page.
How do I now get the user's originally intended destination (mywebpage.html) from Spring Security, so I can redirect the user to that page once he/she has created an account?
For the record, security.xml
<http auto-config="true">
<intercept-url pattern="/login" access="permitAll()" />
<intercept-url pattern="/flow-entry.html" access="hasRole('ROLE_USER')"/>
<form-login
login-page="/login"
authentication-failure-url="/login?error=true" />
<logout logout-success-url="/login" />
</http>
login form
<form name='f' action="login" method='POST'>
<table style="text-align:left" class="w3-table" >
<tr style="text-align:center;color:red" th:if="${loginresponse}">
<td colspan="2" style="text-align:center" th:text="#{${loginresponse}}"> </td>
</tr>
<tr>
<td th:text="#{label.emaillogin}"></td>
<td><input type="text" name="username" value=''/></td>
</tr>
<tr>
<td th:text="#{label.password}">Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><input name="submit" type="submit" class="w3-btn w3-blue w3-hover-aqua w3-round-large" th:value="#{label.ok}" /></td>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
</tr>
<tr style="text-align:center">
<td colspan="2" style="text-align:center"> <span th:text="#{label.register}"></span> </td>
</tr>
</table>
</form>
Controller Method. I need originally intended web page in this method
#RequestMapping(value = "/doRegistration", method=RequestMethod.POST)
public ModelAndView doRegistration(ModelAndView mv, HttpServletRequest request)
{
mv.setViewName("register");
SSm.getLogger().debug("registering new user");
String email = request.getParameter("username");
String email1 = request.getParameter("username1");
if(email.equals(email1))
{
if(email.contains("#")&&email.contains("."))
{
SSm.getLogger().debug("got legit email");
String password = request.getParameter("password");
String password1 = request.getParameter("password1");
if(password.equals(password1))
{
SSm.getLogger().debug("ready to login");
I NEED USERS ORIGINALLY INTENDED DESTINATION RIGHT HERE SO I CAN SET THE VIEW
}
else
{
mv.setViewName("register");
mv.addObject("loginresponse", "message.passwordmismatch");
}
}
else
{
mv.setViewName("register");
mv.addObject("loginresponse", "message.invalidemail");
}
}
else
{
mv.setViewName("register");
mv.addObject("loginresponse", "message.emailmismatch");
}
return mv;
}
You could use a SavedRequestAwareAuthenticationSuccessHandler.
When a non authorized request reaches the ExceptionTranslationFilter, a RequestCache of class HttpSessionRequestCache is created and the original request is saved on it.
This way, if you do not set alwaysUseDefaultTargetUrl to true, httpRequest would be reconstructed and used as target url while correct login is performed.
So, try to #Autowire (I use #Resource instead as I have more than one AuthenticationManager and AuthenticationSuccessHandler in my security config) the AuthenticationSuccessHandler in your controller and calling determineTargetUrl() like this:
I made a little modifications such as use #Valid annotations and implement a Validator to validate the registration form
Security.xml
<beans:bean id="savedRequestSuccesHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/zone4/secured/securedPage.htm" />
</beans:bean>
<security:http pattern="/zone4/**" use-expressions="true" authentication-manager-ref="mainAuthenticationManager">
<security:intercept-url pattern="/zone4/simple/**" access="permitAll()" />
<security:intercept-url pattern="/zone4/secured/**" access="isAuthenticated()"/>
<security:form-login
login-page="/zone4/simple/login.htm"
authentication-failure-url="/login.htm?error=true"
authentication-success-handler-ref="savedRequestSuccesHandler"
username-parameter="email"
password-parameter="password"
login-processing-url="/zone4/secured/performLogin.htm"
/>
<security:logout
logout-url="/zone4/secured/performLogout.htm"
logout-success-url="/zone4/simple/login.htm" />
<security:csrf disabled="true"/>
</security:http>
Controller:
/**
*
*/
package com.eej.ssba2.controller.test;
import java.io.IOException;
import java.util.Arrays;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.eej.ssba2.model.test.zone4.RegisterModel;
import com.eej.ssba2.model.test.zone4.RegisterModelValidator;
/**
*
*/
#Controller
#RequestMapping("/zone4")
public class Zone4TestController {
private Logger logger = Logger.getLogger(this.getClass());
#Resource(name="mainAuthenticationManager")
private AuthenticationManager authenticationManager;
#Resource(name="savedRequestSuccesHandler")
private SavedRequestAwareAuthenticationSuccessHandler successHandler;
#RequestMapping("/simple/unsecuredPage.htm")
public String unsecuredPage(){
return "simple/unsecuredPage";
}
#RequestMapping("/secured/securedPage.htm")
public String securedPage1(){
return "simple/secured/securedPage";
}
#RequestMapping("/secured/securedPage2.htm")
public String securedPage2(){
return "simple/secured/securedPage2";
}
#RequestMapping("/secured/securedPage3.htm")
public String securedPage3(){
return "simple/secured/securedPage3";
}
#RequestMapping("/simple/login.htm")
public String login(){
return "simple/login/login";
}
#RequestMapping(value="/simple/register.htm", method=RequestMethod.GET)
public String register(ModelMap model){
logger.debug("Entrada en register.htm");
if(!model.containsAttribute("registerModel")){
model.addAttribute("registerModel", new RegisterModel());
}
return "simple/login/register";
}
#RequestMapping(value="/simple/register.htm", method=RequestMethod.POST)
public String register(
HttpServletRequest request, HttpServletResponse response,
#Valid RegisterModel registerModel, ModelMap model, BindingResult bindingResult){
logger.info("entrada en register");
RegisterModelValidator userValidator = new RegisterModelValidator();
userValidator.validate(registerModel, bindingResult);
if(bindingResult.hasErrors()){
logger.info("BindingResult has errors: " + bindingResult.getAllErrors());
model.addAttribute("errors", bindingResult.getAllErrors());
model.addAttribute("registerModel", registerModel);
return "simple/login/register";
}
// Your user register business
Authentication authenticated = null;
/*
* If the user is created at this time due to your business logic, you could authenticate it directly
* through the manager
*
authenticated =
this.authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
registerModel.getMail1(),
registerModel.getPassword1()
)
);
*/
authenticated = new UsernamePasswordAuthenticationToken(
registerModel.getMail1(),
registerModel.getPassword1(),
Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))
);
SecurityContextHolder.getContext().setAuthentication(authenticated);
try {
this.successHandler.onAuthenticationSuccess(request, response, authenticated);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Registration model bean:
package com.eej.ssba2.model.test.zone4;
import java.io.Serializable;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import org.apache.log4j.Logger;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import com.eej.ssba2.ApplicationVersion;
/**
*
*
*/
public class RegisterModel implements Serializable{
private Logger logger = Logger.getLogger(this.getClass());
/**
*
*/
private static final long serialVersionUID = 1L;
#NotEmpty
#Pattern(regexp = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*" +
"#[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$|")
public String mail1;
#NotEmpty
#Pattern(regexp = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*" +
"#[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$|")
public String mail2;
#NotEmpty
public String password1;
#NotEmpty
public String password2;
// getters and setters
}
The Validator imiplementation I use to validate the fields in the model:
package com.eej.ssba2.model.test.zone4;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class RegisterModelValidator implements Validator {
#Override
public boolean supports(Class<?> arg0) {
return RegisterModel.class.equals(arg0);
}
#Override
public void validate(Object target, Errors errors) {
RegisterModel user = (RegisterModel) target;
if(!user.getMail1().equals(user.getMail2())){
errors.rejectValue("mail1", "lbl_mail1_and_mail2_must_be_equal");
errors.rejectValue("mail2", "lbl_mail1_and_mail2_must_be_equal");
}
if(!user.getPassword1().equals(user.getPassword2())){
errors.rejectValue("password1", "lbl_pass1_and_pass2_must_be_equal");
errors.rejectValue("password2", "lbl_pass1_and_pass2_must_be_equal");
}
}
Finally, the registration jsp:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login</title>
</head>
<body>
<form:form role="registerModel" commandName="registerModel" method="POST" action="${pageContext.request.contextPath}/zone4/simple/register.htm">
<form:errors path="*" cssClass="errorblock" element="div" />
<fieldset>
<div class="form-group">
<form:input path="mail1" id="mail1" name="mail1" placeHolder="email" />
<form:errors path="mail1" id="mail1" name="mail1" placeHolder="email" cssClass="error" />
</div>
<div class="form-group">
<form:input path="mail2" id="mail2" name="mail2" placeHolder="email" />
<form:errors path="mail2" id="mail2" name="mail2" placeHolder="email" cssClass="error" />
</div>
<div class="form-group">
<form:input path="password1" id="password1" name="password1" placeHolder="password" />
<form:errors path="password1" id="password1" name="password1" placeHolder="password" cssClass="error" />
</div>
<div class="form-group">
<form:input path="password2" id="password2" name="password2" placeHolder="password" />
<form:errors path="password2" id="password2" name="password2" placeHolder="password" cssClass="error" />
</div>
<div class="checkbox">
<label>
<input name="remember-me" id="remember-me" type="checkbox" value="Remember Me">Remember Me
</label>
</div>
<!-- Change this to a button or input when using this as a form -->
<button type="submit" class="btn btn-lg btn-success btn-block" name="submit"><spring:message code="lblRegistration"/></button>
</fieldset>
</form:form>
</body>
</html>

AJax Callback fails (NPE) on selectoneitem

Used this StackOverflow answer to try an implement a submitless form. The page consists of a selectomenu control and a table. On change of the selection I wish to refresh the table body. The page loads without issues, but when the selection is made I get the following error occurs:
10:22:48,241 ERROR [[FacesServlet]] Servlet.service() for servlet FacesServlet threw exception: java.lang.NullPointerException
at com.sun.faces.context.PartialViewContextImpl.createPartialResponseWriter(PartialViewContextImpl.java:441) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.context.PartialViewContextImpl.access$300(PartialViewContextImpl.java:71) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.context.PartialViewContextImpl$DelayedInitPartialResponseWriter.getWrapped(PartialViewContextImpl.java:582) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.context.PartialResponseWriter.startDocument(PartialResponseWriter.java:115) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:199) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:505) [jbossweb-7.0.13.Final.jar:]
at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:445) [jbossweb-7.0.13.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
at java.lang.Thread.run(Thread.java:636) [rt.jar:1.6.0_18]
I'm using JBoss-AS-7.1.1, and the selectonmenu looks like this:
<h:selectOneMenu id="ship"
value="#{shipManager.current}">
<f:selectItems value="#{shipManager.list}"
var="ship"
itemValue="#{ship}"
itemLabel="#{ship.name}" />
<f:ajax listener="#{shipManager.changeShip}" />
</h:selectOneMenu>
If I remove the ajax component then no issues although (of course) the shipManager is not updated.
Once I have the selection made I would then like to add the renderer part to refresh my table body.
Many thanks for any help given.
Steve
As requested here is my XHTML code:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Voyage Cruises</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link type="text/css" rel="stylesheet" media="all" href="/css/screen.css"/>
<link type="text/css" rel="stylesheet" media="all" href="/css/cruise.css"/>
<script src="http://open.mapquestapi.com/sdk/js/v7.0.s/mqa.toolkit.js"></script>
<script src="js/map.js" ></script>
<script src="js/cruise.js" ></script>
</h:head>
<h:body>
<div id="page">
<div id="float-map">
<div id="map"></div>
</div>
<h:form id="ship-form">
<div id="ship-controls">
<div class="float-ctrls">
<img src="/images/action_search.png" alt="Find Ports"/>
</div>
<div>
<span id="ship-selector" >
<h:selectOneMenu id="ship"
value="#{shipManager.current}">
<f:selectItems value="#{shipManager.list}"
var="ship"
itemValue="#{ship}"
itemLabel="#{ship.name}" />
<f:ajax execute="ship" render="#form" listener="#{shipManager.changeShip}" />
</h:selectOneMenu>
</span>
<select id="month" />
<select id="year" />
<br />
<span class="input-container"><b>Tonnage:</b><input id="tonnage" type="text" size="6" value="30,277" /></span>
<span class="input-container"><b>Audit Time:</b><input id="audit" type="text" size="2" value="6" /></span>
<span class="input-container"><b>Fleet:</b><input id="fleet" type="text" size="20" value="P&O" /></span>
</div>
</div>
<table class="cruise">
<thead>
<tr>
<th class="date">Date</th>
<th class="port">Port</th>
<th class="arrive">Arrive</th>
<th class="depart">Depart</th>
</tr>
</thead>
<tbody>
<ui:repeat var="cruise"
value="#{cruiseManager.list}"
varStatus="table">
<tr class="#{table.even ? 'even' : 'odd'}">
<td class="date">
<h:outputFormat value="{0, date,d MMM}">
<f:param value="#{cruise.date}" />
</h:outputFormat>
</td>
<h:panelGroup rendered="#{null != cruise.port}">
<td class="port">#{cruise.port.name}</td>
<td class="arrive">
<h:outputFormat rendered="#{null != cruise.arrival}"
styleClass="#{cruise.arrivalEstimated ? 'est-time' : 'act-time'}"
value="{0, date,HH:mm}">
<f:param value="#{cruise.arrival}" />
</h:outputFormat>
</td>
<td class="depart">
<h:outputFormat rendered="#{null != cruise.departure}"
styleClass="#{cruise.departureEstimated ? 'est-time' : 'act-time'}"
value="{0, date,HH:mm}">
<f:param value="#{cruise.departure}" />
</h:outputFormat>
</td>
</h:panelGroup>
<h:panelGroup rendered="#{null == cruise.port}">
<td class="at-sea" colspan="3">At Sea</td>
</h:panelGroup>
</tr>
</ui:repeat>
</tbody>
</table>
</h:form>
</div>
</h:body>
</html>
And the ShipManager:
package com.nutrastat.voyager.web;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;
import com.nutrastat.voyager.db.HarbourMasterLocal;
import com.nutrastat.voyager.db.ShipEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#ManagedBean
#ViewScoped
public class ShipManager
implements Serializable {
static final long serialVersionUID = -3017226836104715117L;
private transient final Logger log;
private ShipEntity currentShip;
#EJB
private HarbourMasterLocal harbourMaster;
public ShipManager() {
log = LoggerFactory.getLogger(getClass());
}
public ShipEntity getCurrent() {
if (log.isInfoEnabled())
log.info("getCurrent(): " + currentShip);
return currentShip;
}
public void setCurrent(ShipEntity ship) {
if (log.isInfoEnabled())
log.info("setCurrent(" + currentShip + "): " + ship);
currentShip = ship;
}
public void changeShip(AjaxBehaviorEvent evt) {
if (log.isInfoEnabled())
log.info("Ship now: " + currentShip);
}
public List<ShipEntity> getList() {
try {
return harbourMaster.listShips();
} catch (Exception cause) {
log.error("Getting the list of ships", cause);
return new ArrayList<ShipEntity>(0);
}
}
}
Your stack trace looks incomplete in that it doesn't actually refer to your code(which is where I'd expect the npe be thrown). That notwithstanding, your select menu doesn't have a converter, so any other problems aside, your form would probably still not save or register the selection
Implement a JSF converter and declare it on that selectonemenu. This is mandatory when a select type component needs to select and save complex POJO types You can look at this example
Try to get rid of that gigantic <h:form/> in your markup. There are too many other components in that form that could be causing you problems. Break the components into smaller chunks in separate forms
If the scope of your bean is #RequestScoped then change it to #ViewScoped , in general ajax better be done with #ViewScoped... cause new instance of the bean created upon each submit...
#ManagedBean(name="shipManager")
#ViewScoped
Also Make sure that the changeShip method takes AjaxBehaviorEvent as the parameter
(ie)
public void changeShip (AjaxBehaviorEvent event){
//** do your stuf
}
and also specidy the execute and Render attributes inside f:Ajax
<f:ajax execute="ship" render="#form" listener="#{shipManager.changeShip}" />

Resources