Changing from Struts 2.x to Spring 3x MVC - spring

Hi I am new to Spring MVC annotations . I am now on assignment of moving Stuts 2.x controller part to Spring annotation based , I am getting trouble while session.
I struts2 I used session aware , its store the map vales . In spring how can I achieve can any one please help me . ...
its more helpful for me if any one reply..with in week.
here is my struts 2.x action class .
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.cmt.admin.business.AdminService;
import com.cmt.admin.dao.User;
import com.cmt.common.constants.CommonConstants;
public class LoginAction extends CMTAction {
private String userName;
private String profileName;
private String password;
private Map<String, String> securityData;
String pageName = CommonConstants.INDEX;
private String menuName;
#Autowired private AdminService cmtAdminService;
#Override
#SuppressWarnings("unchecked")
public String execute() throws Exception {
if((userName==null || (CommonConstants.EMPTY_STRING).equals(userName)) && (password==null || (CommonConstants.EMPTY_STRING).equals(password))) {
return CommonConstants.INVALID;
}
Map<String, Map<String, String>> securityData = new HashMap<String, Map<String, String>>();
String returnStatus = CommonConstants.SUCCESS;
Map<String,Object> resultData = null;
Boolean validUser = false;
this.getSession().put(CommonConstants.MENU_NAME, CommonConstants.HOME);
resultData = cmtAdminService.loginProcess(userName, password,profileName);
validUser = (Boolean) resultData.get(CommonConstants.IS_VALID_USER);
if (validUser) {
User logggedUser = (User) resultData.get(CommonConstants.LOGGED_INUSER);
this.getSession().put(CommonConstants.LOGGED_INUSER, logggedUser);
securityData = (HashMap<String, Map<String, String>>) resultData.get( CommonConstants.SECURITY_DATA);
this.getSession().put(CommonConstants.SECURITY_DATA, securityData);
returnStatus = getPageSecurityData(pageName); return returnStatus;
} else {
showErrorMessage(CommonConstants.INVALID_USERNAME_PASSWRD_ERROR);
return CommonConstants.INVALID;
}
}
public String index() {
return CommonConstants.INDEX;
}
public String home() throws Exception {
if (this.getSession()==null || this.getSession().get(CommonConstants.LOGGED_INUSER) == null || "".equals(this.getSession().get(CommonConstants.LOGGED_INUSER))) {
return CommonConstants.INVALID;
}
String returnStatus = CommonConstants.SUCCESS;
returnStatus = getPageSecurityData(pageName);
return returnStatus;
}
private String getPageSecurityData(String pageName) throws Exception {
String returnStatus = CommonConstants.SUCCESS;
Map<String, Map<String, String>> securtyData = new HashMap<String, Map<String, String>>();
Map<String, Object> resultData = new HashMap<String, Object>();
Map<String, String> currentPageSecurty = new HashMap<String, String>();
securtyData = (HashMap<String, Map<String, String>>) this.getSession().get( CommonConstants.SECURITY_DATA);
resultData = cmtAdminService.getPageSecurityData(securtyData,pageName);
currentPageSecurty = (HashMap<String, String>) resultData .get(CommonConstants.CURRENT_PAG_SECRTY_INFO);
returnStatus = (String) resultData.get(CommonConstants.PAGE_ACTION);
setSecurityData(currentPageSecurty);
setMenuName((String) this.getSession().get(CommonConstants.MENU_NAME));
return returnStatus;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public Map<String, String> getSecurityData() {
return securityData;
}
public void setSecurityData(Map<String, String> securityData) {
this.securityData = securityData;
}
public void setUsername(String value) {
this.userName = value;
}
public String getUsername() {
return userName;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
public String getProfileName() {
return profileName;
}
public void setProfileName(String profileName) {
this.profileName = profileName;
}
}
This is my CMTAction class
package com.cmt.admin.web.action;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.cmt.admin.dao.User;
import com.cmt.common.constants.CommonConstants;
import com.opensymphony.xwork2.ActionSupport;
public class CMTAction extends ActionSupport implements SessionAware
{
// This Map will contain vales in Session
private Map<String, Object> sessionMap;
protected User getLoggedInUser()
{
User user = (User) this.getSession().get(CommonConstants.LOGGED_INUSER);
return user;
}
protected void showActionMessage(String message)
{
addActionMessage(message);
}
protected void showErrorMessage(String message)
{
addActionError(message);
}
#Override
public void setSession(Map<String, Object> session)
{
this.sessionMap = session;
}
public Map<String, Object> getSession()
{
return sessionMap;
}
}
This is my struts.xml file
<?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="false" />
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.ui.theme" value="css_xhtml" />
<constant name="struts.custom.i18n.resources" value="resources.message,resources.label" />
<package name="default" namespace="/" extends="struts-default,json-default">
<interceptors>
<interceptor name="sessionTimedOut"
class="com.cmt.common.interceptors.SessionTimeOutInterceptor" />
<interceptor name="sessionCheck" class="com.cmt.common.interceptors.SessionCheckInterceptor"/>
<interceptor-stack name="CMTStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="sessionTimedOut" />
<interceptor-ref name="sessionCheck" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="CMTStack"/>
<default-action-ref name="index" />
<global-results>
<result name="index">/jsp/admin/pgLogin.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="sessionTimedOut">/jsp/admin/pgSessionTimedOut.jsp</result>
<result name="invalid">/jsp/admin/pgLogin.jsp</result>
<result name="uploadCodeComments">/jsp/iConfigure/pgUploadCode.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception"
result="error" />
</global-exception-mappings>
<action name="index" method="index" class="LoginAction">
<result name="index">/jsp/admin/pgLogin.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
</action>
<action name="Login" method="execute" class="LoginAction">
<result name="success">/jsp/admin/pgIndex.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
</action>
<action name="Logout" method="logout" class="LogoutAction">
<result name="success">/jsp/admin/pgLogin.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
</action>
<action name="home" method="home" class="LoginAction">
<result name="success">/jsp/admin/pgIndex.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
</action>
<action name="search" method="execute" class="SearchAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success">/jsp/iCRL/pgiCRL.jsp</result>
</action>
<action name="icrl" method="search" class="SearchAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success">/jsp/iCRL/pgiCRL.jsp</result>
</action>
<action name="searchCodes" method="searchCodes" class="SearchAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success" type="json"></result>
</action>
<action name="searchicrl" method="submitPage" class="SearchAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success" type="json"></result>
</action>
<action name="iconfdtl" method="retrieveIConfigureDetails" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success">/jsp/iConfigure/pgiConfigureReviewStep2.jsp
</result>
</action>
<action name="retrieveCodeList" method="retrieveCodeList" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success" type="json">
</result>
</action>
<action name="filterassc" method="filterAssociationCodes" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success" type="json">
</result>
</action>
<action name="codeSearch" method="retrieveIConfigureDetails" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="invalid">/jsp/admin/pgSessionTimedOut.jsp</result>
<result name="success">/jsp/iConfigure/pgiConfigureReviewStep2.jsp
</result>
</action>
<action name="iconfaddcategory" method="retrieveIConfigureViewDetails"
class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success">/jsp/iConfigure/pgiConfigureCategory.jsp</result>
</action>
<action name="iconfviewdtl" method="retrieveIConfigureViewDetails"
class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="reloadconfdtl" method="retrieveIConfigureViewDetails"
class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="populateaddnew" method="showAddNewForm" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="editaddnew" method="populateEditAssociationData" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="saverow" method="saveRowData" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="success">/jsp/iConfigure/pgiConfigureReviewStep2.jsp</result>
</action>
<action name="editassoc" method="saveEditedAddNewData" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="populateOrgUnit" method="populateOrgUnit" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="populateUserAccount" method="populateUserAccount" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result name="invalid">/jsp/admin/pgSessionTimedOut.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="addassoc" method="saveNewCodeAssociation" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="saveNewCategory" method="saveNewCategory" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
<action name="codeView" method="getCodeViewDetails" class="CodeViewAction">
<result name="success">/jsp/iCRL/pgiCRLDetailView.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
</action>
<action name="iPolicyStepThreeSubmit" class="IPolicyAction" method="iPolicyList" >
<result name="success">/jsp/iPolicy/pgiPolicyDetailsStep4.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
</action>
<action name="iPolicyStepFourSubmit" class="IPolicyAction" method="iPolicyList" >
<result name="success">/jsp/iPolicy/pgiPolicy.jsp</result>
<result name="error">/jsp/admin/pgError.jsp</result>
</action>
<action name="findCategoryName" method="findCategoryName" class="IConfigureAction">
<result name="error">/jsp/admin/pgError.jsp</result>
<result type="json" name="success"></result>
</action>
</package>
</struts>

I use the SessionAttributes annotation on my controller to have spring retaining in session some attributes that I will put in my model. Spring transparently put and retrieve from the session these attribute as they are put into the model or injected in a controller method. As the javadoc indicates, this is a good method when the attributes are to be set in session temporarily, and it advices another way to access the session directly for attributes that should stored permanently. This method is described with enough details here.
You should probably go for that.
Alternatively, for your security data for example, you could create a session-scoped bean in your application context of type java.util.HashMap and then inject it into your controller. I don't know if this is a good practice, but the advantage is you can inject this bean in services if needed.

Related

Unable to repopulate values after xml validation in Struts2 [duplicate]

This question already has an answer here:
Struts 2 Validation and Input fields repopulation
(1 answer)
Closed 6 years ago.
I was recently working with a login page with Struts2 framework and for validating the fields i used XML Validation feature provided by Struts2. And the fields are validated but the problem is that, if any of the field is not empty after validation the those field values are not repopulated in the corresponding field.The Example code is given.The version of the framework is 2.5.x.
Login.jsp
<s:form method="post" action="authenticate">
<div class="form-group">
<span class="input-icon">
<s:textfield name="strUserName" id="strUserName" cssClass="form-control" placeholder="Username or Email"></s:textfield>
<i class="fa fa-user"></i>
</span>
<span>
<s:fielderror fieldName="strUserName"/>
</span>
</div>
<div class="form-group">
<span class="input-icon">
<s:password name="strPassword" id="strPassword" cssClass="form-control" placeholder="Password"></s:password> <i class="fa fa-lock"></i>
</span>
<span>
<s:fielderror fieldName="strPassword"/>
</span>
</div>
</s:form>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.action.extension" value=",json"/>
<!-- Set to false before deploying the application -->
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
<constant name="struts.configuration.xml.reload" value="false" />
<!-- constant to define global resource bundle -->
<constant name="struts.custom.i18n.resources" value="globalMessages" />
<constant name="struts.ui.theme" value="simple" />
<package name="<package_name>" namespace="/" extends="struts-default">
<action name="authenticate" class="<Action_class_name>" method="<method_name>">
<interceptor-ref name="store">
<param name="operationMode">STORE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result type="redirectAction">Successpage</result>
<result name="input" type="redirectAction">login</result>
</action>
<action name="login">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<result>login.jsp</result>
</action>
</package>
</struts>
Action_name-validation.xml
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<validator type="requiredstring">
<param name="fieldname">strUserName</param>
<param name="trim">true</param>
<message key="errors.required"></message>
</validator>
<validator type="requiredstring">
<param name="fieldname">strPassword</param>
<param name="trim">true</param>
<message key="errors.required"></message>
</validator>
</validators>
Action_name.java
public class Action_name extends ActionSupport implements ModelDriven<UserModel> {
private UserModel user;
public String method_name() {
if(success){
return SUCCESS;
}else{
return INPUT;
}
}
#Override
public UserModel getModel() {
user = new UserModel();
return user;
}
}
Applicatin - intial run
Application - After Validation
value "xyz" is not repopulated after the validation.
There are two problems:
your login action
<action name="login">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<result>login.jsp</result>
</action>
has only a single interceptor, the MessageStore one.
It should have instead at least the ModelDriven and the Parameters Interceptors to work correctly. For example
<action name="login">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result>login.jsp</result>
</action>
But note that this would lead to infinite recursion due to the MessageStore Interceptor always adding errors and the Workflow Interceptor always returning "input"; to avoid it you should define a secondary defaultStack in your struts.xml with all the intercpetors except the Workflow one, otherwise the MessageStore with RETRIEVE will make it loop or, if you haven't defined an input result for your login action, complaining about a missing input result.
The second error is that you are redirecting, and hence losing the parameters. You're using the MessageStore Interceptor to preserve Action Messages, Action Errors and Field Errors across the redirection, but every other parameter is lost. If you want to preserve a parameter across a redirectAction you must explicitly send it, or store it in session in the source action and retrieving it in the destination action. In your case, it would be better to simply return the JSP in case of input result, instead of redirecting:
<action name="authenticate" class="<Action_class_name>" method="<method_name>">
<interceptor-ref name="store">
<param name="operationMode">STORE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result type="redirectAction">Successpage</result>
<result name="input" >login.jsp</result>
</action>
<action name="login">
<interceptor-ref name="defaultStack" />
<result>login.jsp</result>
</action>

Parse Unity Push Sample not working

I am struggling of using Parse on my Unity android application. Have been working on several days but no success yet. No matter how hard I try, I couldn't get my device token registered for Android which is needed for sending push notifications to android. Below is my sample code and manifest snippet..
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:protectionLevel="signature" android:name="com.JoyDash.Movies.permission.C2D_MESSAGE" />
<uses-permission android:name="com.JoyDash.Movies.permission.C2D_MESSAGE" />
<!--Parse Push notification receiver-->
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.JoyDash.Movies.Receiver" android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.JoyDash.Movies" />
</intent-filter>
</receiver>
<!--<receiver android:name="com.parse.ParsePushBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.JoyDash.Movies" />
</intent-filter>
</receiver>
<service android:name="com.parse.ParsePushService" />-->
#if UNITY_IOS
NotificationServices.RegisterForRemoteNotificationTypes (RemoteNotificationType.Alert |
RemoteNotificationType.Badge |
RemoteNotificationType.Sound);
#endif
//ParsePush.SubscribeAsync
Debug.Log("Registration with Parse Push. : " + Application.platform);
ParsePush.ParsePushNotificationReceived += (sender, args) =>
{
if (Application.platform == RuntimePlatform.Android)
{
AndroidJavaClass parseUnityHelper = new AndroidJavaClass("com.parse.ParseUnityHelper");
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
// Call default behavior.
Debug.Log("Calling Parse from Unity and Payload is : " + args.Payload);
parseUnityHelper.CallStatic("handleParsePushNotificationReceived", currentActivity, args.Payload.ToString());
//parseUnityHelper.CallStatic("handleParsePushNotificationReceived", currentActivity, args.Payload.StringPayload);
}
else if (Application.platform == RuntimePlatform.IPhonePlayer)
{
//IDictionary<string, object> payload = args.Payload;
//foreach (string key in payload)
//{
// Debug.Log("Payload: " + key + ": " + payload[key].ToString());
//}
}
};
//Parse Installation
Debug.Log("Device Token : " + ParseInstallation.CurrentInstallation.DeviceToken);
if (ParseInstallation.CurrentInstallation != null && !string.IsNullOrEmpty(ParseInstallation.CurrentInstallation.DeviceToken))
{
Debug.Log("Device Token : " + ParseInstallation.CurrentInstallation.DeviceToken);
}
else
{
//Create a new parse installation
//ParseInstallation.CurrentInstallation.SaveAsync().ContinueWith(t =>
// {
// if (t.IsFaulted || t.IsCanceled)
// {
// Debug.Log("Parse installation failed to save.");
// }
// else
// {
// Debug.Log("Parse installation saved successfully.");
// }
// });
//ParseInstallation.cre
Debug.Log("There is no installation data received for this device.. Now subscribing to a channel");
ParsePush.SubscribeAsync("Channel01").ContinueWith(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
Debug.Log("Subscription of push notification failed.");
}
else
{
Debug.Log("Push notification subscribed successfully.");
}
});
//installation.
}
"Parse Unity Push Sample not working", agree!! boy, such a pain in the ( Y )
I've been fighting with Unity Parse Pushes for days(a week?) and I just solve it. I am so, so, happy, I want to share my happiness (first time in my life I write at StackOverflow, guess it was about time...)
Not sure if this will solve your problem, but for sure you have something wrong at this line:
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
We have to change "currentActivity" for what ever is your current activity. In my case I have written this:
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject> ("com.unity3d.player.UnityPlayerNativeActivity");
Because that's the name of my activity in my AndroidManifest.xml
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:launchMode="singleTask" android:screenOrientation="landscape">
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Still, it might not solve your problem. So, just in case, I copy paste my code!
AndroidManifest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.XXXX.YYYY" android:versionName="1" android:versionCode="7">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<uses-feature android:glEsVersion="0x00020000" />
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:protectionLevel="signature" android:name="com.XXXX.YYYY.permission.C2D_MESSAGE" />
<uses-permission android:name="com.XXXX.YYYY.permission.C2D_MESSAGE" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/app_icon" android:label="#string/app_name" android:debuggable="false">
<service android:name="com.parse.ParsePushService" />
<receiver android:name="com.parse.ParsePushBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
<category android:name="com.XXXX.YYYY" />
</intent-filter>
</receiver>
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:launchMode="singleTask" android:screenOrientation="landscape">
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" />
<!-- replace #drawable/push_icon with your push icon identifier -->
<meta-data android:name="com.parse.push.notification_icon" android:resource="#drawable/app_icon"/>
</application>
</manifest>
Please, replace com.XXXX.YYYY by -your- bundle identifier, in case of thetnswe would be by com.JoyDash.Movies
(funny thing: there is no GCM BroadcastReceiver as the Parse Push samples says, it was spitting errors like this error setting up push notification using parse.com and android studio)
And then I have a C# Unity Script in one of my GameObjects (actually the same than the one I use to initialize Parse):
using UnityEngine;
using System.Collections;
using Parse;
public class ParsePushRegistration : MonoBehaviour {
// Use this for initialization
void Start () {
#if UNITY_ANDROID
ParsePush.ParsePushNotificationReceived += (sender, args) => {
AndroidJavaClass parseUnityHelper = new AndroidJavaClass ("com.parse.ParseUnityHelper");
AndroidJavaClass unityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject> ("com.unity3d.player.UnityPlayerNativeActivity");
// Call default behavior.
parseUnityHelper.CallStatic ("handleParsePushNotificationReceived", currentActivity, args.StringPayload);
};
#endif
}
}
Hope it helps! If not, let me know... and we will see :)

Struts 2 validation not working

I am trying to use struts 2 custom validation framework for validations, however that does not seem to be working. I am working on a very big project and the module I'm working on, I'm trying to implement this.
The problem struts 2 is not detecting my validation.xml. I tried creating a sample project and and used this validation.xml and it is working, but the same is not working in the project.
I am using model driven , I hope that should not be the problem.
The basic validations provided by action support are working fine but not my validations.
<interceptors>
<interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />
<interceptor name="browserCachingInterceptor" class="com.comviva.im.ui.interceptor.BrowserCachingInterceptor" />
<interceptor name="sessionHijackInterceptor" class="com.comviva.im.ui.interceptor.SessionHijackInterceptor" />
<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
<interceptor-stack name="defaultSecurityStack">
<interceptor-ref name="defaultStack">
<param name="exception.logEnabled">true</param>
<param name="exception.logLevel">DEBUG</param>
</interceptor-ref>
<interceptor-ref name="tokenSession">
<param name="excludeMethods">*</param>
</interceptor-ref>
<interceptor-ref name="sessionHijackInterceptor" />
<interceptor-ref name="browserCachingInterceptor" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="defaultSecurityStack"></default-interceptor-ref>
The interceptor declaration is also fine.
I tried for days but still cant figure out the problem. the only option remaining is debug.
Can anybody suggest me where should I be looking for. Where is the validation.xml file is loaded in ActionInvocation so that I can check if validation file was loaded properly or not.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<field name="nodeId">
<field-validator type="required">
<message key="errors.required"/>
</field-validator>
<field-validator type="int">
<param name="min">1</param>
<param name="max">10000</param>
<message>bar must be between ${min} and ${max}, current value is ${bar}.</message>
</field-validator>
</field>
<field name="selfISDNNumber">
<field-validator type="required">
<message key="errors.required"/>
</field-validator>
</field>
</validators>
This is extract from my action class:
public class NodeAction extends BaseAction implements ModelDriven<NodeConfigurationForm>, ParameterAware ,Preparable {
NodeConfigurationForm nodeConfigForm = new NodeConfigurationForm();
private static final Logger logger = Logger.getLogger(NodeAction.class);
private NodeConfigurationService configurationService;
private List<NodeConfiguration> nodeListTable = null;
Map<String , String[]> requestParams;
private int isFallBackChannelEnable;
private int smsSupportEnable;
private ServletContext servletContext;
MY NodeAction class extends BaseAction which extends ActionSupport which by default is validation aware.So NodeAction should work with custom validations also.
This is extract from my struts.xml regarding actions:
<action name="createGWNode" method="create" class="com.comviva.im.ui.ussdGateway.action.NodeAction">
<result name="success" type="tiles">createGWNode</result>
</action>
<action name="addGWNode" method="add" class="com.comviva.im.ui.ussdGateway.action.NodeAction">
<result name="success" type="chain">listGWNodes</result>
<result name="input" type="tiles">createGWNode</result>
<result name="error" type="tiles">createGWNode</result>
</action>
<action name="editGWNode" method="edit" class="com.comviva.im.ui.ussdGateway.action.NodeAction">
<result name="success" type="tiles">createGWNode</result>
</action>
<action name="updateGWNode" method="update" class="com.comviva.im.ui.ussdGateway.action.NodeAction">
<result name="success" type="redirect">listGWNodes</result>
<result name="input" type="tiles">createGWNode</result>
<result name="error" type="tiles">createGWNode</result>
</action>
And this is my jsp
<s:textfield name="nodeId" required="true" theme="simple" />reado
<s:radio name="status" list="#{'1':'Enable','0':'Disable'}" theme="simple"></s:radio>
<s:textfield name="gwInstanceName" theme="simple" />
<s:textarea name="description" cols="30" rows="2" theme="simple"/>
<s:textfield name="serverIp" theme="simple"/>
<s:textfield name="serverIp" theme="simple" readonly=< s:textfield name="loginUserId" theme="simple"/>
<s:password name="loginPassword" showPassword="true" theme="simple"/>
<s:textfield name=" selfISDNNumber " theme="simple "/>
<s:select name="logLevel " list="logLevelList " theme="simple "/>
Note: Please remove _ Underscore from selfISDN_num
Check proper jar files.
Xwork: Core 2.3.16.2 API
And check getter , setters
Note: Please check package name in struts.xml, does it extend struts-default?
<package name="Registration" namespace="/" extends="struts-default">
...
</package>
Finally found what was going wrong.
The DTD specified in validaiton.xml was wrong. The specifed DTD is for 2.3 onwards. I was using struts with a lower version.
I am now using
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

How to retrieve action error messages using multiple redirect actions in struts2?

I'm using struts2 and my struts.xml looks like this:
<action name="actionA" class="actionAClass">
<result name="success" type="redirectAction">actionD</result>
<result name="error" type="redirectAction">actionB</result>
</action>
<action name="actionB" class="actionBClass">
<result name="success" type="redirectAction">actionC</result>
<result name="error" type="redirectAction">actionC</result>
</action>
<action name="actionC" class="actionAClass">
<result name="success">homepage.jsp</result>
<result name="error">homepage.jsp</result>
</action>
As you can see, actionA error result redirect to actionB and actionB error result redirect to actionC. At the end, I want to display the error message at the homepage.jsp but homepage is loaded only when actionC is called.
However using actions like this, when homepage is loaded, all the action error messages are lost.
I've also tried using interceptors in struts.xml between actions like below but still I'm not able to retrieve the error messages:
<action name="actionA" class="actionAClass">
<interceptor-ref name="store">
<param name="operationMode">STORE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result name="success" type="redirectAction">actionD</result>
<result name="error" type="redirectAction">actionB</result>
</action>
<action name="actionB" class="actionBClass">
<result name="success" type="redirectAction">actionC</result>
<result name="error" type="redirectAction">actionC</result>
</action>
<action name="actionC" class="actionAClass">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result name="success">homepage.jsp</result>
<result name="error">homepage.jsp</result>
</action>
Please help how do I retrieve action error messages using multiple redirect actions.

struts2 errors lost

I trying to use struts2 validation framework. I have a ActionName-validation.xml in place. Entry in the struts.xml is as follows
<action name="registerCandidateStep1" class="candidateAction"
method="registerCandidateStep1">
<result name="success" type="tiles">registerCandidate</result>
<result name="input" type="chain">
<param name="actionName">loadCandidateRegistrationForm</param>
<param name="namespace">/.secureActions</param>
</result>
</action>
<action name="loadCandidateRegistrationForm" class="loadCandidateFromAction"
method="loadCandidateRegistrationForm">
<result name="success" type="tiles">registerCandidate</result>
</action>
on error condition request do get forwarded to "loadCandidateRegistrationForm" but i dont see error on the page. I have included tag in the jsp
StrutsConfig.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.objectFactory" value="spring" />
<constant name="struts.devMode" value="false" />
<constant name="struts.action.extension" value="action" />
<constant name="struts.custom.i18n.resources" value="global" />
<package name="org" namespace="/"
extends="struts-default,json-default">
<result-types>
<result-type name="tiles"
class="org.apache.struts2.views.tiles.TilesResult" />
</result-types>
<global-results>
<result name="welcome" type="tiles">welcome</result>
</global-results>
</package>
<package name="org.unsecureActions" extends="org">
<!--
This package contains such a actions which doesn't need user logged
in.
-->
<action name="welcome" method="forwardAction" class="baseAction">
<result name="success" type="tiles">welcome</result>
</action>
<action name="logout" method="logoutCandidate" class="logoutAction">
<result name="success" type="tiles">welcome</result>
</action>
<action name="loadAdvanceSearchForm" method="loadAdvanceSearch"
class="advanceSearchAction">
<result name="success" type="tiles">advanceSearch</result>
</action>
<!--Candidate workflow actions -->
<action name="registerCandidateStep1" class="candidateAction"
method="registerCandidateStep1">
<interceptor-ref name="store">
<param name="operationMode">STORE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result name="success" type="tiles">registerCandidate</result>
<result name="input" type="redirect">loadCandidateRegistrationForm.action</result>
</action>
<action name="registerCandidateStep2" class="candidateAction"
method="registerCandidateStep2">
<result name="success" type="tiles">registerCandidate</result>
<result name="input" type="tiles">loadCandidateRegistrationForm</result>
</action>
<action name="registerCandidateStep3" class="candidateAction"
method="registerCandidateStep3">
<result type="chain">
<param name="actionName">loginCandidate</param>
<param name="namespace">/org.unsecureActions</param>
</result>
<result name="input" type="tiles">registerCandidate</result>
</action>
<action name="loadCandidateRegistrationForm" class="loadCandidateFromAction"
method="loadCandidateRegistrationForm">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<result name="success" type="tiles">registerCandidate</result>
</action>
<!--Candidate workflow actions -->
<action name="loginCandidate" class="loginAction" method="loginCandidate">
<result name="success" type="tiles">home</result>
<result name="input" type="tiles">welcome</result>
</action>
</package>
<package name="org.secureActions" extends="org">
<!--
This package contains such a actions which needs user must logged in
before executing these.
-->
<interceptors>
<!--
Following interceptor checks for is user logged in before executing
the action.
-->
<interceptor name="contextSecurityInterceptor"
class="org.kovid.matrimony.interceptor.ContextSecurityInterceptor">
</interceptor>
<!--
This stack is as like default stack provided ny Struts Only
difference is at the bottom of folowing stack where we included our
"contextSecurityInterceptor" interceptor.
-->
<interceptor-stack name="applicationStack">
<interceptor-ref name="exception" />
<interceptor-ref name="alias" />
<interceptor-ref name="servletConfig" />
<interceptor-ref name="prepare" />
<interceptor-ref name="i18n" />
<interceptor-ref name="chain" />
<interceptor-ref name="debugging" />
<interceptor-ref name="profiling" />
<interceptor-ref name="scopedModelDriven" />
<interceptor-ref name="modelDriven" />
<interceptor-ref name="fileUpload" />
<interceptor-ref name="checkbox" />
<interceptor-ref name="staticParams" />
<interceptor-ref name="actionMappingParams" />
<interceptor-ref name="params" />
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation" />
<interceptor-ref name="workflow" />
<interceptor-ref name="contextSecurityInterceptor" />
</interceptor-stack>
</interceptors>
<!--
Setting default stack for interceptor taking care of this packageS.
-->
<default-interceptor-ref name="applicationStack" />
<action name="home" method="forwardAction" class="baseAction">
<result name="success" type="tiles">home</result>
</action>
<action name="loadAdvanceSearchForm" method="loadAdvanceSearch"
class="advanceSearchAction">
<result name="success" type="tiles">advanceSearch</result>
</action>
<action name="simpleSearch" method="simpleSearch" class="simpleSearchAction">
<result name="success" type="tiles">search</result>
<result name="input" type="tiles">home</result>
</action>
<action name="advanceSearch" method="advanceSearch" class="advanceSearchAction">
<result name="success" type="tiles">search</result>
</action>
<action name="loadImage" method="loadImage" class="imageAction">
<result name="imageData" type="stream">
<param name="contentType">${imageContentType}</param>
<param name="inputName">imageStream</param>
<param name="contentDisposition">filename="candidate.jpeg"</param>
<param name="bufferSize">${myBufferSize}</param>
</result>
</action>
</package>
</struts>
Action chaining is actively discouraged, and interactions with the validation interceptor is one reason why. You might be able to sneak around it by explicitly mapping some values (like the validation messages) from one action to the next, but... don't chain actions--there's almost never a reason to do so.
Like Dave said, Action Chaining is discouraged.
Action Chaining :
Don't Try This at Home
As a rule, Action Chaining is not recommended.
First explore other options, such as the Redirect After Post
technique.
And if you have good reason to use Redirect After Post, use the
Redirect Result + Message Store Interceptor OR
Redirect Action Result + Message Store Interceptor
Life time of Errors lasts for the current Action. If you forward/redirect to another action, then the errors will be lost.
Use session scope instead. Place ArrayList in session and append your errors/messages.
Action/Interceptor:
Map session = ActionContext.getContext().getSession();
List<String> errors = session.get("errorMessages");
if(errors==null)
session.put("errorMessages", errors=new ArrayList<String>() );
errors.add("Invalid Username/Password. Kindly retry");
JSP:
<s:iterator var="msg" value="#session.errorMessages" >
<p> ${msg} </p>
</s:iterator>
<s:set scope="session" var="errorMessages" value="%{null}" /><%--flush errors--%>

Resources