i have a sx:autocompleter tag in welcome.jsp as shown below. Although, the autocompleter action is getting invoked, the result is not rendering properly and autocomplete is not working.(i have included struts2-dojo-plugin-2.3.8.jar in WEB-INF/lib.)
(DEBUG output in browser shows following message.
DEBUG: please consider using a mimetype of text/json-comment-filtered to avoid potential security issues with JSON endpoints
Details at end of question.)
Following is my code.
welcome.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="/struts-tags" prefix="s"%>
<%# taglib prefix="sx" uri="/struts-dojo-tags"%>
................................
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title>
<sx:head debug="true"/>
</head>
<body>
<s:form action="sub">
.........
<s:url var="fruitsurl" action="fruits"></s:url>
<sx:autocompleter label="Fruits" name="autocompleter1" href="%{fruitsurl}" list="fruitsList"></sx:autocompleter>
..........
<s:submit></s:submit>
</s:form>
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
....................
<struts>
<package name="some-default" extends="struts-default">
<action name="fruits" class="mypack.FruitsAction" method="display">
<result name="success">welcome.jsp</result>
</action>
<action name="sub" class="mypack.SubmitAction">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
FruitsAction.java
package mypack;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
public class FruitsAction extends ActionSupport{
private List fruitsList;
public List getFruitsList() {
return fruitsList;
}
public void setFruitsList(List fruitsList) {
this.fruitsList = fruitsList;
}
public String display() throws Exception {
fruitsList = new ArrayList();
fruitsList.add("apples");
fruitsList.add("oranges");
fruitsList.add("mangoes");
return SUCCESS;
}
}
i have set debug="true" in sx:head and the following DEBUG output is shown in browser when
welcome.jsp is invoked.
DEBUG: please consider using a mimetype of text/json-comment-filtered to avoid potential security issues with JSON endpoints
DEBUG: [SyntaxError: Syntax error]
DEBUG:<!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>Welcome</title><script language="JavaScript" type="text/javascript">
// Dojo configuration djConfig = { isDebug: true,
bindEncoding: "UTF-8"
,baseRelativePath: "/Suburbs/struts/dojo/"
,baseScriptUri: "/Suburbs/struts/dojo/" ,parseWidgets : false
};</script> <script language="JavaScript" type="text/javascript"
src="/Suburbs/struts/dojo/struts_dojo.js"></script>
<script language="JavaScript" type="text/javascript"
src="/Suburbs/struts/ajax/dojoRequire.js"></script>
<script language="JavaScript" type="text/javascript">
dojo.hostenv.writeIncludes(true);</script>
<link rel="stylesheet" href="/Suburbs/struts/xhtml/styles.css" type="text/css"/>
<script language="JavaScript" src="/Suburbs/struts/utils.js" type="text/javascript"></script>
<script language="JavaScript" src="/Suburbs/struts/xhtml/validation.js" type="text/javascript"></script>
<script language="JavaScript" src="/Suburbs/struts/css_xhtml/validation.js" type="text/javascript"></script>
</head><body>
<form id="sub" name="sub" action="/Suburbs/sub.action" method="post">
<table class="wwFormTable"><tr>
<td class="tdLabel"><label for="sub_autocompleter1" class="label">Fruits:</label></td>
<td
> <input dojoType="struts:ComboBox" dataUrl="/Suburbs/fruits.action" id="sub_autocompleter1" name="autocompleter1" keyName="autocompleter1Key" visibleDownArrow="true" />
<option value="apples">apples</option>
<option value="oranges">oranges</option>
<option value="mangoes">mangoes</option> </select></td></tr>
<script language="JavaScript" type="text/javascript">djConfig.searchIds.push("sub_autocompleter1");</script>
<tr>
<td colspan="2"><div align="right"><input type="submit" id="sub_0" value="Submit"/>
</div></td></tr></table></form></body></html>
please guide me as to what could be wrong with the code.
thanks,
Your action needs to return JSON, as described on the Ajax and JavaScript Recipes page. (Link to previous version due to a wiki export issue). Nutshell: use the JSON plugin.
<action name="fruits" class="mypack.FruitsAction" method="display">
<result type="json">
<param name="root">fruits</param>
</result>
</action>
Note that I'm explicitly setting the "root" element to your list of fruits. I'm also eliminating the redundancy in the name of the list of fruits; it's a list of fruits–its name should be fruits.
Lastly, the Dojo plugin has been deprecated for at least a couple of years now, for a variety of reasons. I'd strongly consider using something like the Struts 2 jQuery Plugin or simply using raw Dojo if you have a need for Dojo explicitly.
Thanks to Dave Newton, i have below solution to my issue.
i modified the code to use JSON along with autocompleter and
included struts2-json-plugin-2.3.8.jar in WEB-INF/lib.
providing modified code below:
welcome.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="/struts-tags" prefix="s"%>
<%# taglib prefix="sx" uri="/struts-dojo-tags"%>
...........
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title>
<sx:head/>
</head>
<body>
<s:form action="sub">
.......................
<s:url var="fruitsurl" namespace="/autocompleter" action="getfruits"></s:url>
<sx:autocompleter label="Fruits" name="autocompleter1" href="%{fruitsurl}"></sx:autocompleter>
.......................
<s:submit></s:submit>
</s:form>
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
............
<struts>
<package name="autocompleter" namespace="/autocompleter" extends="json-default">
<action name="getfruits" class="mypack.FruitsAction">
<result type="json">
<param name="root">fruits</param>
</result>
</action>
</package>
<package name="some-default" extends="struts-default">
<action name="sub" class="mypack.SubmitAction">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
FruitsAction.java
package mypack;
import java.util.HashMap;
import java.util.Map;
import com.opensymphony.xwork2.ActionSupport;
public class FruitsAction extends ActionSupport{
Map<String,String> fruits;
public Map<String, String> getFruits() {
fruits=new HashMap<String,String>();
fruits.put("apples", "ap");
fruits.put("oranges", "or");
fruits.put("mangoes", "ma");
return fruits;
}
public void setFruits(Map<String, String> fruits) {
this.fruits = fruits;
}
}
Follwing is the solution using jquery plugin instead of dojo plugin.
(Replaced dojo plugin with struts2-jquery-plugin-3.6.0.jar in WEB-INF/lib
in Eclipse.)
welcome.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="/struts-tags" prefix="s"%>
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
..................
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title>
<sj:head jqueryui="true"/>
</head>
<body>
<s:form action="sub">
.......................
<s:url var="fruitsurl" namespace="/autocompleter" action="getfruits"></s:url>
<sj:autocompleter label="Fruits" name="autocompleter1" href="%{fruitsurl}"></sj:autocompleter>
......................
<s:submit></s:submit>
</s:form>
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
................
<struts>
<package name="autocompleter" namespace="/autocompleter" extends="json-default">
<action name="getfruits" class="mypack.FruitsAction">
<result type="json" name="success">
<param name="root">fruitNames</param>
</result>
</action>
</package>
<package name="some-default" extends="struts-default">
<action name="sub" class="mypack.SubmitAction">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
FruitsAction.java
package mypack;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import com.opensymphony.xwork2.ActionSupport;
#SuppressWarnings("serial")
public class FruitsAction extends ActionSupport{
private String term;
List<String> fruitList=new ArrayList<String>();
private String[] fruitNames;
#Override
public String execute() throws Exception {
fruitList.add("apples");
fruitList.add("mangoes");
fruitList.add("pears");
fruitList.add("grapes");
if (StringUtils.isNotBlank(term)){
ArrayList<String> subList=new ArrayList<String>();
for (int i=0;i<fruitList.size();i++){
if (StringUtils.startsWithIgnoreCase(fruitList.get(i), term)){
subList.add(fruitList.get(i));
}
}
fruitNames=subList.toArray(new String[subList.size()]);
}else{
fruitNames=null;
}
return SUCCESS;
}
public String[] getFruitNames() {
return fruitNames;
}
public void setTerm(String term) {
this.term = term;
}
}
in FruitsAction.java, the string 'term' is what we type into the autocompleter.
the action gets invoked everytime we type in a new letter.
i referred the following urls for the above solution.
http://code.google.com/p/struts2-jquery/wiki/AutocompleterTag
http://www.coderanch.com/t/537518/Struts/struts-jquery-autocompleter
Related
I am new to Struts 2 framework. I have made a program for understanding modelDriven interceptor. But I am unable to execute it. Following are the list of files and in the end there is a output (error).
index.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="/struts-tags" prefix="s"%>
<!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>Insert title here</title>
</head>
<body>
<%-- <jsp:useBean id="ent" class="pack.Entity" scope="session" /> --%>
<s:form method="get" action="go">
<s:textfield name="t1" label="Name"></s:textfield>
<s:password name="p1" label="Password"></s:password>
<s:submit value="accept"></s:submit>
</s:form>
</body>
</html>
Entity.java:
package actions_pack;
public class Entity {
private String t1;
private String p1;
public String getP1() {
return p1;
}
public void setP1(String p1) {
this.p1 = p1;
}
public Entity() {
super();
// TODO Auto-generated constructor stub
}
public String getT1() {
return t1;
}
public void setT1(String t1) {
this.t1 = t1;
}
}
GoAction.java:
package actions_pack;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor;
import com.opensymphony.xwork2.util.ValueStack;
public class GoAction implements ModelDriven<Entity> {
private Entity en;
public Entity getEn() {
return en;
}
public void setEn(Entity en) {
this.en = en;
}
public String execute(){
System.out.println("inside action");
if(en.getT1().equalsIgnoreCase("nitin")){
return "success";
}
else{
return "failure";
}
}
#Override
public Entity getModel() {
System.out.println("inside model driven....");
en=new Entity();
return en;
}
}
struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="dd">
<result-types>
<result-type name="dispatcher"
class="org.apache.struts2.dispatcher.ServletDispatcherResult"
default="true" />
</result-types>
<interceptors>
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="modelDriven"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="go" class="actions_pack.GoAction">
<interceptor-ref name="myStack"></interceptor-ref>
<result name="success" type="dispatcher" >/one/welcome.jsp</result>
<result name="failure" type="dispatcher">/one/error.jsp</result>
</action>
</package>
</struts>
welcome.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="/struts-tags" prefix="s" %>
<!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>Insert title here</title>
</head>
<body>
Welcome, <s:property value="t1"/>
</body>
</html>
web-page output(500 error):
HTTP Status 500 -
type Exception report
message
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.lang.NullPointerException
actions_pack.GoAction.execute(GoAction.java:24)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:450)
com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:289)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:252)
com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:563)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.34 logs.
Apache Tomcat/7.0.34
In struts.xml file I don't want to use/extend struts-default package. Although, when I include params interceptor entry along with modelDriven interceptor in struts.xml, problem solves. What is the reason behind this. Can any one guide me?
You have a property in the action class that needs initialize prior to the action execution. You can do it in many ways.
The way you have chosen relies on modelDriven interceptor which is running before your action is executed. It invokes getModel() to push it on top of the valueStack. So, your entity property is being initialized. If you remove this interceptor you will get NullPointerException when the action is executed.
If your Entity is a simple POJO that you can instantiate yourself then simply do it inline instead of in getModel().
private Entity en = new Entity();
#Override
public Entity getModel() {
System.out.println("inside model driven....");
return en;
}
Next part is about params interceptor. It uses OGNL to populate a top object that is a model if you have used modelDriven interceptor prior params interceptor.
Living it along with your action allows to initialize some properties you reference in the execute().
For example t1 should be initialized.
I am trying to get the exception via struts2 to display the global results jsp but its not working and instead I am getting a java exception show in console. Also would like to add that If i use interceptor-ref exception individually to an action its working fine but globally not working as intended.
Here is my struts.xml, just addded a simple global results and exceptions.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts-devmode" value="true"></constant>
<package name="user" extends="struts-default">
<global-results>
<result name="myresult">globalresult.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping result="myresult" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
<action name="UserAction" class="actionclasses.UserAction"
method="execute">
<interceptor-ref name="timer"></interceptor-ref>
<interceptor-ref name="params"></interceptor-ref>
<result name="input">index.jsp</result>
<result name="success">success.jsp</result>
</action>
<action name="LoginAction">
<result type="redirect">login.jsp</result>
</action>
</package>
</struts>
My UserAction class from where exception is raised.
package actionclasses;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
String userName;
String passWord;
public String execute()
{
System.out.println(userName);
int a=10/0;
return "success";
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
My login.jsp, my login page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib prefix='s' uri='/struts-tags' %>
<!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>User Login</title>
</head>
<body>
<h1>Login to Web page</h1>
<s:form action="UserAction" method="post">
<s:textfield name="userName" label="Enter UserName" />
<s:password name="passWord" label="Enter Password" />
<s:submit value="submit" />
</s:form>
</body>
</html>
Once you specify any interceptors you must specify all interceptors.
I am using struts2 for implementing my application. In my application I have to implement two drop downs, value of the second drop down is dependent on first drop down. I got reference from an example and implemented my code accordingly, but still not getting the result. Please give your suggestion to make this code work.
SupporterAction.java
package action;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import entityBean.TicketDataBean;
import entityBean.UserBean;
import entityListener.SupporterListener;
import entityManager.Application;
#SuppressWarnings("serial")
public class SupporterAction extends ActionSupport{
private String application;
private String number;
private List<String> applicationNames;
List<String> ticketNumber;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public List<String> getApplicationNames() {
return applicationNames;
}
public void setApplicationNames(List<String> applicationNames) {
this.applicationNames = applicationNames;
}
public List<String> getTicketNumber() {
return ticketNumber;
}
public void setTicketNumber(List<String> ticketNumber) {
this.ticketNumber = ticketNumber;
}
public String getApplication() {
return application;
}
public void setApplication(String application) {
this.application = application;
}
public String getJSON() {
return execute();
}
#SuppressWarnings("unchecked")
public String execute()
{
#SuppressWarnings("rawtypes")
Map session = ActionContext.getContext().getSession();
System.out.println(session.get("currentSessionUser"));
applicationNames = new ArrayList<String>();
UserBean userBean = (UserBean)session.get("currentSessionUser");
List<Application> applicationObj = userBean.getApplication();
for (Application obj : applicationObj)
{
System.out.println(obj.getApplicationName());
applicationNames.add(obj.getApplicationName());
}
session.put("ApplicationNames",applicationNames);
System.out.println("Hello");
System.out.println(application);
if(application != null)
{
ticketNumber=new ArrayList<String>();
System.out.println("Hello 1");
SupporterListener sl = new SupporterListener();
List<TicketDataBean> tdbList = sl.getPendingTickets(application);
if(!tdbList.isEmpty())
{
for(TicketDataBean td : tdbList)
{
ticketNumber.add(td.getNumber());
}
session.put("logined","true");
session.put("TicketNumber",ticketNumber);
}
}
return "success";
}
}
Supporter.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags" %>
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<!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>Insert title here</title>
</head>
<body>
<s:form id="formSelectReload" theme="simple" cssClass="yform" action="getApplicationList">
<fieldset>
<div class="type-text">
<label for="application">Application : </label>
<s:url var="remoteurl" action="getApplicationList" namespace="/"/>
<sj:select href="%{remoteurl}" id="application" name="application"
list="applicationNames" onChange="reloadsecondlist" emptyOption="false"
headerKey="-1" headerValue="Please Select a Application" />
</div>
<s:property value="#session.ApplicationNames"/>
<div class="type-text">
<label for="number">Ticket Number: </label>
<s:url var="remoteurl" action="getApplicationList" namespace="/"/>
<sj:select href="%{remoteurl}" id="ticketNumber" formIds="formSelectReload"
reloadTopics="reloadsecondlist" name="number"
list="ticketNumber"
emptyOption="false"
headerKey="-1" headerValue="Please Select a Ticket Number"/>
</div>
<div class="type-button">
<sj:submit
id="submitFormSelectReload"
/>
</div>
</fieldset>
</s:form>
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<constant name="struts.custom.i18n.resources" value="ApplicationResources" />
<package name="login" extends="struts-default">
<action name="login"
class="action.LoginAction"
method="execute">
<result name="success">/Home.jsp</result>
<result name="error">/InvalidLogin.jsp</result>
<result name="INVALID SESSION">/Home.jsp</result>
</action>
<action name="logout"
class="action.LoginAction"
method="logout">
<result name="success">/Login.jsp</result>
</action>
<action name="register">
<result>/Register.jsp</result></action>
<action name="importexcel">
<result>/ImportExcel.jsp</result></action>
<action name="supporter" class="action.SupporterAction"
method="execute">
<result name="success">/Supporter.jsp</result></action>
<action name="registeruser"
class="action.RegisterAction"
method="register">
<result name="success">/UserLogged.jsp</result>
<result name="error">/InvalidLogin.jsp</result>
<result name="INVALID SESSION">/Register.jsp</result>
</action>
<action name="importExcel"
class="action.ImportExcelAction"
method="importExcel">
<result name="success">/Home.jsp</result>
<result name="error">/InvalidLogin.jsp</result>
<result name="INVALID SESSION">/Home.jsp</result>
</action>
</package>
<package name="default" extends="struts-default,json-default" namespace="/">
<action name="getApplicationList"
class="action.SupporterAction" >
<result type="json" />
</action>
</package>
</struts>
jar files
Image of jar files
Result I am getting is
Image of result
As we can see in Image of result, list is being populated but I am not able to get it in drop down. Please suggest something.
Thank you in advance for your answers.
The prepare() interceptor is your friend.
https://struts.apache.org/docs/prepare-interceptor.html
I am new to Struts 2 and trying to see whether I can populate a drop down box with the list of values but still I am not able to get it working.
Following is my Action class (Portal.java):
public class Portal extends ActionSupport {
private Map Products;
private String product;
public Portal(){
Products = new HashMap();
Products.put("1", "Java");
Products.put("2", "C++");
}
public Map getProducts() {
return Products;
}
public void setProducts(Map Products) {
this.Products = Products;
}
public String getProduct() {
return product;
}
public void setProduct(String product) {
this.product = product;
}
public String execute() {
return SUCCESS;
}
}
Following is my Portal.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<!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>Portal</title>
</head>
<body>
<h2>Portal</h2>
<s:form action="result" namespace="/">
<h4>
<s:select label="Select Product"
name="product"
headerKey="-1"
headerValue="Select Product"
list="Products"
/>
</h4>
<h4>
<s:submit label="Submit" name="submitButton" align="center" />
</h4>
</s:form>
Following is my result.jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<!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>Results Page</title>
</head>
<body>
<h1>Portal</h1>
<h4>
Selected Product : <s:property value="product"/>
</h4>
</body>
</html>
Following is my struts.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<constant name="struts.ognl.allowStaticMethodAccess" value="false" />
<package name="default" extends="struts-default" namespace="/">
<action name="result" class="com.abc.xyz.Portal">
<result name="error">Portal.jsp</result>
<result name="success">Result.jsp</result>
</action>
</package>
</struts>
Following is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" 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" id="WebApp_ID" version="2.5">
<display-name>Portal</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>Portal.jsp</welcome-file>
</welcome-file-list>
</web-app>
When I execute this on Tomcat 6 server, I get following error:
SEVERE: Servlet.service() for servlet jsp threw exception
tag 'select', field 'list', name 'product': The requested list key 'Products' could
not be resolved as a collection/array/map/enumeration/iterator type. Example:
people or people.{name} - [unknown location]
But when I replace list="Products" with list="#{'1':'Java', '2':'C++'}", then it works perfectly fine .. I don't know what am I missing so that the list is not being shown.
Please help.
Memory is not allocated for Map Products.
Just before setting the values for the Products write -
Products = new Map();
then set the values to the map. This will help to populate the values of the Products on the View.
Java is case sensitive... list="products" is what you want not list="Products"
Edit: see the comments under this question, you should have a getter or change the access to Products to public.
According to Struts2 data prepopulation should be done by PreparableInterceptor and you have to override prepare method.
public void prepare() throws Exception {
Products = new HashMap();
Products.put("1", "C#");
Products.put("2", "Java");
}
Actually when you open your Portal.jsp it look on valuestack but it didn't get that's why this error come.Because on load the corresponding action is not calling,you have to call action onload.Implement Preparable interface and override the prepare method and in that method you write your code.``
Refer my answer to this similar question: Struts2 list couldn't be resolved
For additional details refer:
https://struts.apache.org/docs/message-resource-files.html
I am trying to write small login application in struts 2.Session is b eing created successfully.In welcome.jsp "logout" option is given.On logout control will be redirected to Logout.jsp.
My problem is after logout session variables are destroyed but pages are storing in browser cache.If click back button of browser i am able to see welcome.jsp.
For clearing cache "ClearCacheInterceptor" is used.I don't understand where i am making mistake.
Instead of clearing browser every time is there any to overcome this prooblem ? Is my approach correct ? Please suggest me.
Login.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%#taglib uri="/struts-tags" prefix="s" %>
<!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=UTF-8">
<title>Login</title>
</head>
<body>
<s:form action="login">
<s:textfield name="myname"></s:textfield>
<s:submit value="submit"></s:submit>
</s:form>
</body>
</html>
Struts.xml
<interceptors>
<interceptor name="clear-cache" class="ActionClasses.ClearCacheInterceptor" />
</interceptors>
<action name="login" class="ActionClasses.LoginAction" >
<interceptor-ref name="clear-cache" />
<result name="success">Welcome.jsp</result>
<result name="error">Login.jsp</result>
</action>
<action name="logout" class="ActionClasses.Logout">
<interceptor-ref name="clear-cache" />
<result name="success">Logout.jsp</result>
</action>
LoginAction.java
package ActionClasses;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class LoginAction extends ActionSupport implements SessionAware
{
/**
*
*/
private static final long serialVersionUID = 1L;
private String myname;
private Map<String , Object> s;
public String execute()throws Exception
{
s=ActionContext.getContext().getSession();
s.put("login", myname);
return "success";
}
public void setMyname(String s)
{
myname=s;
}
public String getMyname()
{
return myname;
}
#Override
public void setSession(Map<String, Object> arg0) {
// TODO Auto-generated method stub
s=arg0;
}
}
ClearcacheInterceptor.java
package ActionClasses;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.StrutsStatics;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class ClearCacheInterceptor extends AbstractInterceptor{
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext context=(ActionContext)invocation.getInvocationContext();
HttpServletResponse response=(HttpServletResponse)context.get(StrutsStatics.HTTP_RESPONSE);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
String result=invocation.invoke();
System.out.println("check result="+result);
return result;
}
}
Logout.java
package ActionClasses;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class Logout extends ActionSupport {
public String execute(){
Map<String,Object> s=ActionContext.getContext().getSession();
s.remove("login");
ActionContext.getContext().getSession().clear();
return "success";
}
}
Welcome.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# page contentType="text/html; charset=UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<s:include value="CheckLogin.jsp"></s:include>
<%# taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
</head>
<body>
<font color="white"></font>
Welcome<s:property value="#session['login']"/>
<s:a href="logout">Logout</s:a>
</body>
</html>
Logout.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
log out successful !!
</body>
</html>
CheckLogin.jsp
<%# taglib prefix="s" uri="/struts-tags" %>
<%# page language="java" contentType="text/html" import="java.util.*"%>
<html>
<head>
<title>Check validate!</title>
</head>
<body>
This is session validation page!
<s:if test="#session.login != 'Jagan'">
<jsp:forward page="Login.jsp" />
</s:if>
</body>
</html>
Well that's a very common issue and this is with respect to your browser cache issue rather than struts2 or any other framework at all.
we have face same problem since when you hit the back button of browser the request is not being send to the server rather it is being serves from the browser cache.you will only notice things when you try to do some work and it will come up with error that you are no longer being logged in.
though you can use certain header like no-cache etc but they are being obeyed by the browser is not certain.
only workaround to this problem as per my understanding is to use https (secure browsing) for your work and than use the header (no-cache. cache-expiry etc) since when you browse application under secure mode these header will be followed by the server and browser.
i hope this will try to give you an idea, just to check redirect to https protocol when your logout and it will solve your problem