I'm using eclipse to implement with the native Struts and hybernate support an application to display a series of links in a page. I'm getting the error:
javax.servlet.jsp.JspException: Cannot find bean: "ListeActeur" in scope: "session"
I've checked a lot of sites and forums, and nothing seems to fix this.
My struts-config:
<struts-config>
<form-beans type="org.apache.struts.action.ActionFormBean">
<form-bean name="ListeActeur" type="mesForms.strust.ListeActeur"/>
<form-bean name="vérifCritère" type="mesForms.strust.vérifCritère"/>
</form-beans>
<action-mapping>
</action>
<action path="/Liste"
parameter="/vue/Invitation.jsp"
name="ListeActeur scope="request validate="false"
type="mesAction.struts.ListeActeurAction">
<forward name="s" path="/vue/NewFile.jsp" redirect="false" />
</action>
</action-mappings>
</struts-config>
ListeActeurAction:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest req, HttpServletResponse res) throws Exception {
System.out.println("Action");
ListeActeur ListeActeur= (ListeActeur) form;
String query = "select * from Acteur " ;
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Iterator results = session.createSQLQuery(query).list().iterator();
List <Acteur> lis = new ArrayList<Acteur>();
while((results.hasNext()))
{
Acteur gg =new Acteur();
Object[] row = (Object[]) results.next();
gg.setActeurId((Integer)row[0]);
gg.setNomActeur((String)row[2]);
lis.add(gg);
}
req.getSession(true).setAttribute("lis", lis);
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
ListeActeur.setLis( lis);
req.setAttribute("formu", ListeActeur.getLis());
return mapping.findForward("s");
}
}
ListeActeur:
public class ListeActeur extends ActionForm {
private List <Acteur> lis=null;
public List <Acteur> getLis(){
return lis;}
public void setLis(List <Acteur> lis){this.lis=lis;}
public void reset(ActionMapping mapping, HttpServletRequest request) {
lis = new ArrayList<Acteur>();
}
I really dont know what to do. Im a newbie in Struts.Thanks in advance!
You have
<action path="/Liste" scope="request" .../>
and
<logic:iterate ... scope="session" >
no wonder you get this exception. If you configure Struts to store the form bean in the request, don't try to fetch it from the session in your JSP.
Related
When I use the below code it's working fine and change the theme, but the problem is if one of the user logged and change the theme it effects to the every user in the system. what I want is to effect the theme only for the particular user but not for every one.
Web.xml
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>#{settingsController.userTheme}</param-value>
</context-param>
primeface (.xhtml)
<h:outputLabel for="userTheme" value="Theme Name *:" style="width: 300px"/>
<p:selectOneMenu id="userTheme" value="#{settingsController.userTheme}" style="width:200px"
required="true" requiredMessage="Theme Name is Required" >
<f:selectItems value="#{settingsController.themeMap}"/>
</p:selectOneMenu>
SettingsController.java class
#ManagedBean(name = "settingsController")
#SessionScoped
#Controller
public class SettingsController {
private String userTheme = "start" ;
private Map<String , String> themeMap ;
#PostConstruct
public void init (){
setThemeMapInit( );
}
public String getUserTheme() {
return userTheme;
}
public void setUserTheme(String userTheme) {
this.userTheme = userTheme;
}
public Map<String, String> getThemeMap() {
return themeMap;
}
public void setThemeMapInit() {
themeMap = new LinkedHashMap<String, String>();
themeMap.put("Aristo", "aristo");
themeMap.put("After-noon", "afternoon");
themeMap.put("After-Work", "afterwork");
themeMap.put("Black-Tie", "black-tie");
themeMap.put("Blitzer", "blitzer");
themeMap.put("Bluesky", "bluesky");
themeMap.put("Bootstrap", "bootstrap");
themeMap.put("Casablanca", "casablanca");
themeMap.put("Cupertino", "cupertino");
themeMap.put("Dark-Hive", "dark-hive");
themeMap.put("Delta", "delta");
themeMap.put("Excite-Bike", "excite-bike");
themeMap.put("Flick", "flick");
themeMap.put("Glass-X", "glass-x");
themeMap.put("Home", "home");
themeMap.put("Hot-Sneaks", "hot-sneaks");
themeMap.put("Humanity", "humanity");
themeMap.put("Overcast", "overcast");
themeMap.put("Pepper-Grinder", "pepper-grinder");
themeMap.put("Redmond", "redmond");
themeMap.put("Rocket", "rocket");
themeMap.put("Sam", "sam");
themeMap.put("Smoothness", "smoothness");
themeMap.put("South-Street", "south-street");
themeMap.put("Start", "start");
themeMap.put("Sunny", "sunny");
themeMap.put("Swanky-Purse", "swanky-purse");
themeMap.put("UI-Lightness", "ui-lightness");
}
public void setThemeMap(Map<String, String> themeMap) {
this.themeMap =themeMap;
}
public void sumbitUserSettings (){
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
try {
ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());
} catch (IOException ex) {
Logger.getLogger(SettingsController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Every Spring bean is a Singletone by default, that's why all users are affected, despite of #SessionScoped.
You can't use #ManagedBean and #Controller at the same time, see why.
The best way to combine Spring and JSF in the same app, is to use Joinfaces.
With Joinfaces your bean will end up looking like this
#Named
#SessionScoped
public class SettingsController {
Related:
JSF vs. Spring MVC
I'm using spring webflow v2.4.8 in my app, and trying to bind the model properties using <binder></binder>. But my collection objects (list1, list2 both ArrayList) never get bound. If I remove the <binder></binder> altogether, all properties are getting correctly bound, but in my case that is not an option.
Do I need to use some custom converter here? Any help greatly appreciated
<view-state id="myId" model="myModel" view="myView" >
<binder>
<binding property="list1"/>
<binding property="list2"/>
<binding property="string1"/>
<binding property="string2"/>
.
.
.
</binder>
.
.
.
</view-state>
It's been a while, but in my project I have a custom ConversionService, so maybe you can try using one like this:
[EDIT]
Here is an example of a converter using a service (that gets the object from the db)
#Named
public class StringToMyType extends StringToObject {
#Inject
private MyTypeService service;
public StringToMyType(MyType myObject) {
super(myObject);
}
#Override
protected Object toObject(String id, Class<?> targetClass) throws Exception {
if (id != null && id.length != 0) {
return service.findById(new Long(id));
} else return null;
}
#Override
protected String toString(Object myObject) throws Exception {
return Objects.toString(((MyType) myObject).getId());
}
}
and add it here
public class CustomDefaultConversionService extends DefaultConversionService {
#Override
protected void addDefaultConverters() {
super.addDefaultConverters();
addConverter(new MyTypeConverter()
addConverter(new ObjectToCollection(this));
}
}
it needs to then be registered this way (xml):
<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator" conversion-service="conversionService"/>
<bean id="conversionService" class="path.to.converter.CustomDefaultConversionService"/>
hope this helps
I am trying to handle session timeout requests in my struts2 application using an Interceptor. Below are the files related to this:
Web.xml:
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
Struts.xml:
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="sessionInterceptor"
class="com.platform.web.security.SessionInterceptor" />
</interceptors>
<action name="doLogin"
class="com.platform.web.action.LoginAction">
<result name="input">/login/login.jsp</result>
<result name="error">/login/login.jsp</result>
<result type="chain">menuAction</result>
</action>
<action name="menuAction"
class="com.platform.web.action.MenuAction">
<interceptor-ref name="sessionInterceptor"/> //Interceptor included here
<result name="SUCCESS">/jsp/main.jsp</result>
<result name="ERROR">/login/login.jsp</result>
<result name="input">/jsp/myFavourite.jsp</result>
</action>
Interceptor Class:
public class SessionInterceptor extends AbstractInterceptor implements StrutsStatics {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public String intercept(ActionInvocation invocation) throws Exception {
final ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context
.get(HTTP_REQUEST);
HttpSession session = request.getSession(false);
// Is there a "user" object stored in the user's HttpSession?
//Object user = session.getAttribute("User");
if (session == null) {
// The user has not logged in yet.
// Is the user attempting to log in right now?
//String loginAttempt = request.getParameter(LOGIN_ATTEMPT);
/* The user is attempting to log in. */
/*if (!StringUtils.isBlank(loginAttempt)) {
return invocation.invoke();
}*/
return "timeout";
} else {
return invocation.invoke();
}
}
}
LoginAction:
public class LoginAction extends MesActionSupport implements ServletRequestAware {
#Override
public String execute() throws Exception {
setActionNameForAudit("execute123");
FILE_LOGGER.debug("Entering into execute() ... ");
String strSessionId = "";
if (isValidUser == true) {
user = getUser();
strSessionId = request.getSession(true).getId();
setServletRequest(request);
session.put("SessionId", strSessionId);
setSession(session, user);
ServletActionContext.getRequest().getSession().setAttribute("User", user);
FILE_LOGGER.debug("Exit from LoginAction.execute() ... ");
return SUCCESS;
} else {
return ERROR;
}
}
MenuAction:
public class MenuAction extends MesActionSupport implements SessionAware, ParameterAware, RequestAware {
#Override
public String execute() throws Exception {
setActionNameForAudit("execute ");
User user = null; // To store current user
Map<String, ArrayList<String>> category = null; // To store all Menu
// Categories.
StringBuffer menu = new StringBuffer(""); // To store Menu String
StringBuffer dashboardMenu = new StringBuffer("");
// user = (User)(request.getSession().getAttribute("User")==null ? null : request.getSession().getAttribute("User")); //Request object IS NULL HERE!!
user = (User) (mapSession.get("User") == null ? null : mapSession
.get("User")); // mapSession object IS NULL HERE
FILE_LOGGER.debug("user is " + user == null);
if (user != null) {
menu = menuView.getMenu(user);
mapSession.put("Menu", menu.toString());
mapSession.put("dbMenu", dashboardMenu.toString());
ret = "SUCCESS";
} else if (user == null) {
ret = ERROR;
} else {
ret = SUCCESS;
}
return ret;
}
Flow is like this:
1. Login screen opens
2. User enters credentials and submits
3. LoginAction is called, user is authenticated
4. If valid user - MenuAction is called. Else redirect to Login.jsp
According to the above code, the session gets created in the LoginAction, control reaches the Interceptor where the session object is checked. If session exists the control reaches MenuAction.
But when this happens, the request object gets reset to NULL! Earlier when I was not using an interceptor, the flow was working completely fine between LoginAction and MenuAction.
Does the interceptor resets the HTTPRequest? and hence the Session? As a result I am not able to proceed.
Any help?
I have many comments on this code/configuration, some trivial, some not.
There's zero reason to create your own session; don't.
When you declare an interceptor in an action configuration you must declare all interceptors. As configured, only the session interceptor is running for menuAction.
That means no parameters will be filled, since no other interceptors are running.
In general, only use SessionAware to access the session. There is very rarely a need to access the request directly.
Obviously the interceptor doesn't "set the request to null", that doesn't even make sense.
I have no idea what your LoginAction is supposed to be doing. What's the intent of lines like setServletRequest(request); or setSession(session, user);? There's nothing about those two lines that look correct.
Name your success and error results just that, "success" and "error" (lower case), if you're going to use the ActionSupport.SUCCESS and ActionSupport.ERROR constants. If you're not using those constants in this code, I'd recommend using other names for them, because it will confuse anybody that has actually used Struts 2 before.
When posting code samples please remove stuff that isn't relevant. Particularly when you don't explicitly set syntax highlighting it makes things much more difficult to read.
Don't use code like if (isValidUser == true), use if (isValidUser).
Mind your conditionals: stuff like if (user == null) ... else if (user != null) ... else ... makes zero sense. The user is null, or it isn't: there's no third option.
Avoid unnecessary, confusing logic, like User currentUser = (User) (mapSession.get("User") == null ? null : mapSession.get("User")); which basically says "If it's null, use null, otherwise return the value you just got, but get it again." WHY???
Comments like User user = null; // To store current user are completely worthless. Isn't it obvious what User user is? A user. Not obvious enough? How about User currentUser???
Name plurals (e.g., collections) as something plural. A map of category names to lists isn't a single category.
Don't declare variables far away from where they're used; it's very confusing.
Put your JSP pages under WEB-INF somewhere to disallow direct client access.
Avoid unnecessary language constructs, like when an if branch returns, an else isn't strictly necessary, and IMO, it adds noise. Similarly, consider returning as soon as you know you're returning. The latter is a bit more controversial, but I think people are coming around to realizing it's okay to have multiple return points in short methods, and IMO it's easier to think about.
Use less code to say things. Create little utility methods to wrap up trivial functionality so it doesn't pollute the mainline code.
Use action chaining almost never.
There's more, but that's enough for now. Here's the actual relevant code, cleaned up. Some of it isn't actually relevant but I left it in anyway.
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="sessionInterceptor" class="com.platform.web.security.SessionInterceptor" />
</interceptors>
<action name="doLogin" class="com.platform.web.action.LoginAction">
<result name="input">/WEB-INF/jsp/login/login.jsp</result>
<result name="error">/WEB-INF/jsp/login/login.jsp</result>
<result type="redirectAction">menuAction</result>
</action>
<action name="menuAction" class="com.platform.web.action.MenuAction">
<interceptor-ref name="sessionInterceptor"/>
<result name="success">/WEB-INF/jsp/main.jsp</result>
<result name="input">/WEB-INF/jsp/myFavourite.jsp</result>
</action>
public class SessionInterceptor extends AbstractInterceptor implements StrutsStatics {
#Override
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
HttpSession session = request.getSession(false);
// session will almost *never* be null. Check for a valid user object.
if (session == null) {
return "timeout";
}
return invocation.invoke();
}
}
public class LoginAction extends MesActionSupport implements ServletRequestAware {
#Override
public String execute() throws Exception {
if (!isValidUser) {
return ERROR;
}
user = getUser();
String strSessionId = request.getSession(true).getId();
setServletRequest(request);
session.put("SessionId", strSessionId);
setSession(session, user);
ServletActionContext.getRequest().getSession().setAttribute("User", user);
return SUCCESS;
}
}
public class MenuAction extends MesActionSupport implements SessionAware, ParameterAware, RequestAware {
#Override
public String execute() throws Exception {
User currentUser = (User) mapSession.get("User");
if (currentUser == null) {
return ERROR;
}
Map<String, List<String>> categories; // Left in for naming.
StringBuffer menu = menuView.getMenu(user);
mapSession.put("Menu", menu.toString());
StringBuffer dashboardMenu = new StringBuffer("");
mapSession.put("dbMenu", dashboardMenu.toString());
return SUCCESS;
}
}
There's no way you can tell between whether the session has timed out or it just hasn't been created yet in your interceptor, unless you add some tracking to your front-end, in primitive case it could be just a single request parameter.
A combination of HttpSessionListener and Servlet3 + AJAX Push notifications would be the right way to do it.
Consoder the following code:
<h:commandButton value="do" action="#{testBacking.do}">
<f:ajax execute="#all" render="#all" listener="#{testBacking.listener}"/>
</h:commandButton>
I want to have a custom tag (with value based on server logic), in the Ajax response XML, something like the following:
<isValidationFailed> true </isValidationFailed>
I can use this data to re-enable the button (which was disabled when Ajax begin, to avoid double clicks) if validation is failed.
How can I achieve this (preferably without using any JSF 3rd party libraries)?
EDIT:
The example code, more precisely, should be like this:
<h:commandButton id="myButton" value="do" action="#{testBacking.do}">
<f:ajax execute="id1" render="id2 myButton" listener="#{testBacking.listener}"/>
</h:commandButton>
This is only possible with a custom PartialViewContext which you load into your JSF application using a PartialViewContextFactory. The custom PartialViewContext should in turn return a custom PartialResponseWriter on PartialViewContext#getResponseWriter(). In this custom PartialResponseWriter, you should be able to add extensions to the XML response by calling startExtension() and endExtension() in endDocument(). Something like:
#Override
public void endDocument() throws IOException {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("name1", "value1");
attributes.put("name2", "value2");
startExtension(attributes);
write("lorem ipsum");
endExtension();
super.endDocument();
}
This will then end up in the XML response as
<extension name1="value1" name2="value2">lorem ipsum</extension>
This is available and traversable by data.responseXML in jsf.ajax.addOnEvent() function.
Here's a full kickoff example how you could utilize it in your particular case:
MyPartialViewContextFactory which provides the custom partial view context:
public class MyPartialViewContextFactory extends PartialViewContextFactory {
private PartialViewContextFactory wrapped;
public MyPartialViewContextFactory(PartialViewContextFactory wrapped) {
this.wrapped = wrapped;
}
#Override
public PartialViewContext getPartialViewContext(FacesContext context) {
return new MyPartialViewContext(wrapped.getPartialViewContext(context));
}
}
MyPartialViewContext which provides the custom partial response writer:
public class MyPartialViewContext extends PartialViewContextWrapper {
private PartialViewContext wrapped;
private PartialResponseWriter writer;
public MyPartialViewContext(PartialViewContext wrapped) {
this.wrapped = wrapped;
this.writer = new MyPartialResponseWriter(wrapped.getPartialResponseWriter());
}
#Override
public PartialResponseWriter getPartialResponseWriter() {
return writer;
}
#Override
public void setPartialRequest(boolean isPartialRequest) {
wrapped.setPartialRequest(isPartialRequest);
}
#Override
public PartialViewContext getWrapped() {
return wrapped;
}
}
MyPartialResponseWriter which writes <extension id="myextension"> with the body as JSON):
public class MyPartialResponseWriter extends PartialResponseWriter {
public MyPartialResponseWriter(ResponseWriter wrapped) {
super(wrapped);
}
#Override
public void endDocument() throws IOException {
startExtension(Collections.singletonMap("id", "myextension"));
write("{\"validationFailed\": " + FacesContext.getCurrentInstance().isValidationFailed() + "}"); // Consider a JSON serializer, like Google Gson.
endExtension();
super.endDocument();
}
}
To get it to run, register the factory as follows in faces-config.xml:
<factory>
<partial-view-context-factory>com.example.MyPartialViewContextFactory</partial-view-context-factory>
</factory>
Here's how you can access, parse and use the <extension id="myextension"> in your jsf.ajax.addOnEvent():
jsf.ajax.addOnEvent(function(data) {
if (data.status == "success") {
var args = JSON.parse(data.responseXML.getElementById("myextension").firstChild.nodeValue);
if (args.validationFailed) {
// ...
}
else {
// ...
}
}
});
However, your particular functional requirement can be achieved in a different, likely simpler, manner. Just let the ajax request update the button itself and let the button's disabled attribute evaluate true when there's means of a successful postback.
<h:commandButton id="myButton" value="do" action="#{testBacking.do}"
disabled="#{facesContext.postback and not facesContext.validationFailed}">
<f:ajax execute="id1" render="#this id2" listener="#{testBacking.listener}"/>
</h:commandButton>
I have a problem with my Declarative Services. I have 2 bundles, one is a server provider and another the user interface that consumes the service.
On server side, the implementation is:
public boolean checkUser(){
return true;
}
And the XML file inside OSGi-INF folder:
<component name="ZBService">
<implementation class="service.ZBService" />
<service>
<provide interface="service.IZBService" />
</service>
</component>
On client side, the implementation is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
IZBService zb;
public void setZBService(IZBService eventAdmin) {
this.zb = eventAdmin;
}
public void unsetZBService(IZBService eventAdmin){
if(this.zb == eventAdmin){
this.zb = null;}
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And XML file:
<component name="ZBService">
<implementation class="main.java.com.gwt.app.server.GreetingServiceImpl" />
<service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service>
<reference name="zb" interface="service.IZBService" bind="setZBService" unbind="unsetZBService" cardinality="0..n" policy="dynamic" />
</component>
Also, I have included the tag Service-Component on manifest file and I have deployed the equinox ds bundle that is ACTIVE.
The client is a GWT user interface, then I inject the service reference into server side of GWT. Well, when I deploy the application on Equinox it runs, but when I push the button, I launch an event to call ZBService. I have debugged the application and the error is zb attribute is null. It is to say, the dependence is nos injected. However the services are exposed on Equinox. If I write services on Equinox console, the services are deployed. Then, my conclusion is the error is due to the injection does not perform.
I would like to know if someone knows what is the reason??
Thanks a lot in advance!!
Nice day
EDIT:
I did your suggestions but it doesn't run. I change the component names and condinality/policy. The result is the same --> NullPointerException due to the injection isn't done.
Also I have debug the application to see if the methods bind and/or unbind are called, but they aren't.
The complete class is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
static protected IZBService zb;
public GreetingServiceImpl(){
System.out.println("Constructor GreetingServiceImpl");
}
public IZBService getZb() {
return zb;
}
public void setZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
public void unsetZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Cache the current thread
Thread currentThread = Thread.currentThread();
// We are going to swap the class loader
ClassLoader oldContextClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(this.getClass().getClassLoader());
super.service(req, resp);
currentThread.setContextClassLoader(oldContextClassLoader);
}
public void activate(ComponentContext context) {
System.out.println("Creating new greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public void activate() {
System.out.println("Activando la referencia al servicio");
}
public void deactivate(ComponentContext context) {
System.out.println("Deactivating greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And the XML client is:
<?xml version="1.0" encoding="UTF-8" ?>
<scr:component name="serviceZB" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<implementation class="main.java.com.gwt.app.server.GreetingServiceImpl" />
<!-- <service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service> -->
<reference name="zb" interface="service.IZBService"
bind="setZb" unbind="unsetZb" cardinality="1..1"
policy="static" />
</scr:component>
Why isn't the service injected if the service is deployed???
Here is a list of things you can try:
First, remove the "static" of zb, that could be the problem.
If you are using Equinox, add the -Dequinox.ds.print=true flag to the VM arguments and see more information about parsing XMLs and so
Of course, add sysouts to setZB and unsetZB :)
Remember that IZBService implementation needs a constructor without arguments
If you are using Equinox use the "list -c" command to obtain information of each component (it's cool because says exactly why a component is not registered).
Set the "inmediate=true" in XMLs to force to inmediatly activation.
You have both components with the same name, , which is kind of awkward when discussing them.
The reference on the client side has: cardinality="0..n" policy="dynamic". Which means it can be activated with zero to n references. Yet your code does not handle this. It seems to expect exactly one reference. Perhaps you should use cardinality="1..1" policy="static".