Error in Select box - struts2

This is my Assignemployee.jsp file code
<s:form action="AssignEmployee" name="myForm">
<s:select name="pname" list="projectlist" headerKey="0" label="Select a country" />
<s:submit/>
</s:form>
This is my projectlist.java action file
package myPack;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
public class projectlist extends ActionSupport implements ServletRequestAware {
private static final long serialVersionUID = 1L;
HttpServletRequest request;
private List<String> projectlist;
public List<String> getProjectlist() {
return projectlist;
}
public void setProjectlist(List<String> projectlist) {
this.projectlist = projectlist;
}
public void setServletRequest(HttpServletRequest request)
{
this.request = request;
}
public HttpServletRequest getServletRequest(){
return request;
}
public String getDefaultSearchEngine() {
return "yahoo.com";
}
public projectlist()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection con=DriverManager.getConnection("jdbc:mysql:///pmt","root","shree");
ps=con.prepareStatement("select * from addproject");
ResultSet res = ps.executeQuery();
while(res.next())
{
projectlist = new ArrayList<String>();
projectlist.add(res.getString("pname"));
}
ps.close();
con.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public String execute()throws Exception
{
return SUCCESS;
}
public String display() {
return NONE;
}
}
And This is struts.xml
<action name="AssignEmployee" class="myPack.projectlist" method="display">
<result name="success">assignemployee.jsp</result>
</action>
When i am running application i get an error like
SEVERE: Servlet.service() for servlet [jsp] in context with path [/PTMS] threw exception [tag 'select', field 'list', name 'pname': The requested list key 'projectlist' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]] with root cause
tag 'select', field 'list', name 'pname': The requested list key 'projectlist' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]
How to solve this error?

There are two problems:
Project list creation is broken, and
The first access to the form is broken.
1) You're creating a new list for every row in the result set:
while (res.next()) {
projectlist = new ArrayList<String>();
projectlist.add(res.getString("pname"));
}
This should look closer to:
projectlist = new ArrayList<String>();
while (res.next()) {
projectlist.add(res.getString("pname"));
}
It also appears you never actually call this method, although it's difficult to tell since the code is essentially illegible without indentation or any valuable whitespace. Where you call it is open to some debate; it could be in the getter itself, a prepare() method (and the action would implement Prepareable), the execute() method, etc.
These kinds of things should likely go into a service, however, as a testability aid.
2) I'm not convinced your initial visit to the JSP is being handled correctly. It should:
a) Go through a Struts 2 action,
b) Call the projectlist initializer, and
c) Forward to the JSP with the form.
If all those criteria are met, you will not get that error.

Related

Grails Spring Security Get Roles for the Current Page

I was wondering if anyone knows an elegant way to get all the roles in the spring security plugin that have access to the current page.
I am using spring security and it's configured to use RequestMap domain objects.
The permissions in my app are pretty complex so I wanted to make a tag at the bottom of each page displaying the roles need to use the page.
I was doing a query for the request map but I want to make sure the way I match the url is the same as the way the plugin does.
Ideally I wouldn't have to run a query at all.
Grails version 2.2.1 Spring Security Plugin version 1.2.7.3
Thanks in advance
I got this to work by adding the following two classes to my src/java.
Class 1
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
FilterInvocationSecurityMetadataSource oldBean;
#Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
FilterInvocation filterInvocation = (FilterInvocation) o;
HttpServletRequest request = filterInvocation.getHttpRequest();
request.setAttribute("PAGEROLES", oldBean.getAttributes(filterInvocation));
return oldBean.getAttributes(o);
}
#Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return oldBean.getAllConfigAttributes();
}
#Override
public boolean supports(Class<?> aClass) {
return FilterInvocation.class.isAssignableFrom(aClass);
}
public Object getOldBean() { return oldBean; }
public void setOldBean(FilterInvocationSecurityMetadataSource oldBean) { this.oldBean = oldBean; }
}
Class 2
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
public class FilterSecurityMDSExtractor implements BeanPostProcessor, BeanFactoryAware {
private ConfigurableListableBeanFactory bf;
private FilterInvocationSecurityMetadataSource metadataSource = new MyFilterInvocationSecurityMetadataSource();
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof FilterInvocationSecurityMetadataSource) {
((MyFilterInvocationSecurityMetadataSource) metadataSource).setOldBean((FilterInvocationSecurityMetadataSource) bean);
return metadataSource;
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.bf = (ConfigurableListableBeanFactory)beanFactory;
}
}
I then added the following to resources.groovy
beans = {
filterSecurityMDSExtractor(FilterSecurityMDSExtractor)
}
Basically I am stuffing the user roles into the request
request.setAttribute("PAGEROLES", oldBean.getAttributes(filterInvocation));
then all I have to do is call the following
request.getAttribute("PAGEROLES");
to get the roles back out. I pieced together my solution by stealing from other great posts on Stackoverflow. Someone else might have a better solution but so far this is working for me.

Managed bean converter injection

Hi guys I have a problem with jsf managed bean and #PersistenceUnit. I'm using this converter
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import mn.bsoft.crasmonclient.model.Customer;
/**
*
* #author D
*/
#ManagedBean
#RequestScoped
#FacesConverter(value="convertToConverter")
public class ConvertToCustomer implements Converter{
#PersistenceUnit(unitName = "CrasmonClientPU")
private EntityManagerFactory entityManagerFactory;
private EntityManager em;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
try {
em = entityManagerFactory.createEntityManager();
Object ret = em.find(Customer.class, new Integer(value));
return ret;
} catch (ConverterException e) {
System.out.println(e.getFacesMessage());
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
try {
Customer pa = (Customer) value;
return String.valueOf(pa.getCustomerId());
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
}
and I got null pointer exception on EntityManagerFactory. In my faces-config file I have:
<converter>
<converter-id>convertToCustomer</converter-id>
<converter-class>crasmonclient.converter.ConvertToCustomer</converter-class>
</converter>
Did I miss something? I don't understand why getting null pointer.
Make sure in your WAR project, there is a persistence.xml file. Furthermore, it's not possible to use #ManagedBean and #FacesConverter at the same time. You need to remove #FacesConverter and <converter> to avoid confusion and use the converter exclusively as managed bean as follows:
<h:inputText converter="#{convertToCustomer} />
Besides, why don't you inject the #PersistenceContext directly:
#PersistenceContext
EntityManager em;

Select Menu JSF to CDI differences

I want to use the arquillian warp test framework for a JSF project I am developing. I understand that I need to use the CDI annotations instead of the JSF ones to get this to work. I am using #ViewScoped beans so I have included seam-faces in my project to deal with this (i am running on JBoss 7). I have modified my beans to use #Named and where I was using #PostConstruct I have put this into the constructor which all seems to be okay.
When I access a view with a selectOneMenu it never has any list items. Here is the code form the view and the bean.
View:
<h:selectOneMenu value="#{ngoBean.ngo.country}" >
<f:selectItems value="#{ngoBean.countryValues}" />
</h:selectOneMenu>
Bean:
import com.a.Facade;
import com.a.CountryEnum;
import com.a.GoverningBody;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
*/
#Named("ngoBean")
#ViewScoped
public class NgoBean implements Serializable {
private GoverningBody ngo = new GoverningBody();
private List<GoverningBody> ngoList;
private boolean edit;
private List<SelectItem> countryValues;
#EJB(beanName = "NgoFacadeImpl")
private Facade<GoverningBody> ngoController;
public NgoBean(){
}
#PostConstruct
public void init(){
//TODO this is a bad way of loading db data i should change it
ngoList = ngoController.findAll();
countryValues = initCountryValues();
}
public void add(){
ngoList.add(ngoController.save(ngo));
//reset the variable
ngo = new GoverningBody();
}
public void edit(GoverningBody item) {
this.ngo = item;
edit = true;
}
public void save() {
ngo = ngoController.update(ngo);
edit = false;
}
public void delete(GoverningBody item) {
ngoController.delete(item);
ngoList.remove(item);
}
public List<GoverningBody> getNgoList() {
return ngoList;
}
public GoverningBody getNgo() {
return ngo;
}
public boolean isEdit() {
return edit;
}
public List<SelectItem> getCountryValues() {
return countryValues;
}
public void setCountryValues(List<SelectItem> countryValues) {
this.countryValues = countryValues;
}
public List<SelectItem> initCountryValues() {
List<SelectItem> items = new ArrayList<>(CountryEnum.values().length);
int i = 0;
for(CountryEnum g: CountryEnum.values()) {
items.add(new SelectItem(g, g.getName()));
}
System.out.println("items = " + items);
return items;
}
}
I tried annotating the method with #Factory("countryValues") but this didn't seem to help.
This problem was unrelated to the symptom. The root cause of the problem was an incorrectly located beans.xml this should have be in the WEB-INF directory of the war not the META-INF directory of the ear.
I also changed the seam-faces dependency to use apache CODI, this is not necessary but this uses #ViewAccessScoped instead of #ViewScoped the different name is less ambiguous I think.

Insert a bean into a Converter

I have the following ApplicationScoped bean
package es.caib.gesma.gesman.data;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import es.caib.gesma.gesman.ejb.Dao;
#ManagedBean(name="priorityList")
#ApplicationScoped
public class PriorityList {
#EJB
Dao daoEjb;
private List<Priority> priorities = null;
public PriorityList() {
}
#PostConstruct
public void refresh() {
this.priorities = daoEjb.findPriorities();
}
public List<Priority> getPriorities() {
return this.priorities;
}
public Priority fromId(int id) {
for(Priority priority : this.priorities) {
if (priority.getId() == id) {
return priority;
}
}
return null;
}
}
I try to inject that bean inside a Converter
package es.caib.gesma.gesman.data.converter;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import es.caib.gesma.gesman.data.Priority;
import es.caib.gesma.gesman.data.PriorityList;
#ManagedBean
#ApplicationScoped
public class PriorityConverter implements Converter {
#ManagedProperty("#{priorityList}")
private PriorityList priorityList;
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
...
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
...
}
public void setPriorityList(PriorityList priorityList) {
System.out.println("SET PRIORITYLIST " + priorityList);
this.priorityList = priorityList;
}
}
Whenever I try to access the property, it is null. The setter is never called.
From this question and this one, it looks like it is not possible to inject the bean the usual way (please correct me if I am wrong). There is any alternative so I avoid having to get the entire list of values from the EJB (= database access) each time?
You can't (currently) inject dependencies into converters. However, if you can use Seam 3, the seam-faces module will enable this. You don't need to do anything special, just have the seam-faces JAR (and any of its dependencies) in the classpath and injection into converters will magically work. Just watch out for other unintended side-effects (I've noticed differences in transaction boundaries when the seam-persistence JAR is in the classpath).
I think you should be able to pull this bean out from the HttpSession (it works for me in PhaseListener with SessionScoped bean)
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
SessionForm sessionBean = (SessionForm) session.getAttribute("priorityList");
Or if I may borrow article from BalusC about JSF communication, on the bottom is described how to make a converter from ManagedBean (so you could easily inject your ApplicationScoped bean there)

Struts2 request as null

Very strange error I have, I am getting request as null when I try to access it. I always used the same method to get it, but now I am having this error.
My Action look like this:
package com.deveto.struts.actions;
import com.deveto.hibernate.mappings.Slider;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.util.ServletContextAware;
/**
*
* #author denis
*/
public class ContentAction extends ActionSupport implements ServletContextAware {
HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);
ActionContext ac = ActionContext.getContext();
ServletContext sc = (ServletContext) ac.get(ServletActionContext.SERVLET_CONTEXT);
#Override
public String execute() throws Exception {
System.out.println("request: " + request);
return SUCCESS;
}
public ActionContext getAc() {
return ac;
}
public void setAc(ActionContext ac) {
this.ac = ac;
}
public HttpServletRequest getRequest() {
return request;
}
public void setRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletResponse getResponse() {
return response;
}
public void setResponse(HttpServletResponse response) {
this.response = response;
}
public ServletContext getSc() {
return sc;
}
public void setSc(ServletContext sc) {
this.sc = sc;
}
public void setServletContext(ServletContext sc) {
this.sc = sc;
}
}
And now I can't do nothing, the request is always null
request: null
Implement the ServletRequestAware Interface and set your request variable there instead of doing that during construction.
But normally you don't need access to the request as the params interceptor of struts does all the work the request object is needed for.
From the documentation of the ServletRequestAware-Interface:
All Actions that want to have access to the servlet request object must implement this interface.
This interface is only relevant if the Action is used in a servlet environment.
Note that using this interface makes the Action tied to a servlet environment, so it should be avoided if possible since things like unit testing will become more difficult.

Resources