I have an Enum like below:
public enum ElectionEventStatus {
NEW("enum.electioneventstatus.new"),
POLLING_NOMINATIONS("enum.electioneventstatus.pollingnominations"),
POLLED_NOMINATIONS("enum.electioneventstatus.pollednominations"),
POLLING_VOTES("enum.electioneventstatus.pollingvotes"),
POLLED_VOTES("enum.electioneventstatus.polledvotes"),
COMPLETED("enum.electioneventstatus.completed"),
INVALIDATED("enum.electioneventstatus.invalidated"),
;
public static final EnumSet<ElectionEventStatus> closedStatuses = EnumSet.of(POLLED_VOTES, COMPLETED);
private final String messageKey;
private ElectionEventStatus(String messageKey) {
this.messageKey = messageKey;
}
public String getMessageKey() {
return messageKey;
}
}
How can I refer to the closedStatus Enumset in jsp? I have enabled static access in struts.xml
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
and tried to access the EnumSet like this but it did not work(I have verified the package name was correct). Thanks.
<s:if test="%{electionEventStatus in #net.tangs.business.electionevent.constants.ElectionEventStatus#closedStatuses}">
Related
Is there any way to map json payload to Model bean.? If possible, please provide me an example.
Following are the classes I am using.
package com.sample;
import java.io.Serializable;
public class Employee implements Serializable{
private String firstName;
private String lastName;
private int id;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Employee [firstName=").append(firstName)
.append(", lastName=").append(lastName).append(", id=")
.append(id).append("]");
return builder.toString();
}
}
Following is my action class.
package com.sample.controller;
import com.opensymphony.xwork2.ModelDriven;
import com.sample.Employee;
public class EmployeeController implements ModelDriven<Employee> {
private String name = "Hari krishna";
Employee emp = new Employee();
public String addEmployee() {
System.out.println(emp);
return "success";
}
#Override
public Employee getModel() {
return emp;
}
}
Following is my struts.xml
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" extends="json-default">
<interceptors>
<interceptor-stack name="jsonStack">
<interceptor-ref name="json">
<param name="enableSMD">true</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="addEmployee" class = "com.sample.controller.EmployeeController" method = "addEmployee">
<interceptor-ref name="jsonStack"></interceptor-ref>
<result type="json" />
</action>
</package>
</struts>
When I call the action "addEmployee", with json data "{"firstName":"Hari","id":123,"lastName":"assds"}" I am getting following response. I set content type to text/json.
{
"model": {
"firstName": null
"id": 0
"lastName": null
}-
}
I am posting data using Advanced Rest Client.
when you send the json data from client to server, send them as string and in action class create a normal String variable to receive and hold the json's string.
Then, you can manually populate your bean from string using json parser,
or use a lib like google gson that has a build in features for this purposes.
Google Gson is a Java serialization/deserialization library that can convert Java Objects into JSON and back.
You can create your own struts Interceptor to wrap this process or implements it directly inside your action class.
I'm attempting to inject a dependency that varies by the state passed in. For example, if the state is Wisconsin, I want to inject one class, but if it's Illinois, I want another. It's not 1-for-1, but 7 states for one and 3 for another.
Is there a way in Spring.net to have a list of values to check against in the config xml?
This is the subject of chapter 6.1 "Mapping runtime values to abstractions" of the book Dependency Injection in .NET. The solution suggested there is to use an Abstract Factory. Your abstract factory might look like:
public interface IStateAlgorithmFactory
{
IStateAlgorithm Create(string state);
}
And inject this factory on your consumer that knows which state to process. To get an IStateAlgorithm his consumer then calls y
alg = _factory.Create("Illnois");
Optionally, you could create a simple factory that maps state names to instances managed by your spring container if you want full configuration control.
Simple example
I imagine you have several classes that implement a certain IStateAlgorithm:
public interface IStateAlgorithm
{
string ProcessState(string stateName);
}
public class EchoingStateAlgorithm : IStateAlgorithm
{
public string ProcessState(string stateName)
{
return stateName;
}
}
public class ReverseEchoingStateAlgorithm : IStateAlgorithm
{
public string ProcessState(string stateName)
{
return new string(stateName.Reverse().ToArray());
}
}
And that there is a certain Consumer that needs to pick an algorithm based on a runtime value. The consumer can be injected with a factory, from which it can retrieve the algorithm it needs:
public class Consumer
{
private readonly IStateAlgorithmFactory _factory;
public Consumer(IStateAlgorithmFactory factory)
{
_factory = factory;
}
public string Process(string state)
{
var alg = _factory.Create(state);
return alg.ProcessState(state);
}
}
A simple factory implementation would simply switch on the state value, use an if, or look in internal list:
public interface IStateAlgorithmFactory
{
IStateAlgorithm Create(string state);
}
public class StateAlgorithmFactory : IStateAlgorithmFactory
{
private string[] _reverseStates = new[] {"Wisconsin", "Alaska"};
public IStateAlgorithm Create(string state)
{
if(_reverseStates.Contains(state))
return new ReverseEchoingStateAlgorithm();
return new EchoingStateAlgorithm();
}
}
Spring.Net Configurable example
If you would like to be able to configure your IStateAlgorithm in your spring configuration, you can introduce a LookupStateAlgorithmFactory. This example assumes that your IStateAlgorithms are stateless and can be shared among consumers:
public class LookupStateAlgorithmFactory : IStateAlgorithmFactory
{
private readonly IDictionary<string, IStateAlgorithm> _stateToAlgorithmMap;
private readonly IStateAlgorithm _defaultAlgorithm;
public LookupStateAlgorithmFactory(IDictionary<string, IStateAlgorithm> stateToAlgorithmMap,
IStateAlgorithm defaultAlgorithm)
{
_stateToAlgorithmMap = stateToAlgorithmMap;
_defaultAlgorithm = defaultAlgorithm;
}
public IStateAlgorithm Create(string state)
{
IStateAlgorithm alg;
if (!_stateToAlgorithmMap.TryGetValue(state, out alg))
alg = _defaultAlgorithm;
return alg;
}
}
The xml config could be:
<object id="lookupFactory"
type="LookupStateAlgorithmFactory, MyAssembly">
<constructor-arg ref="echo" />
<constructor-arg>
<dictionary key-type="string" value-type="IStateAlgorithm, MyAssembly">
<entry key="Alaska" value-ref="reverseEcho"/>
<entry key="Wisconsin" value-ref="reverseEcho"/>
</dictionary>
</constructor-arg>
</object>
<object id="echo" type="EchoingStateAlgorithm, MyAssembly" />
<object id="reverseEcho" type="ReverseEchoingStateAlgorithm, MyAssembly" />
I am facing an issue with <s:hidden /> The value is not populated.
<s:hidden name="objectName.stringName" /> works.
<s:hidden name="stringName" /> doesn't. I have getters and setters and I tried in debug mode. The getter function is called.
I also tried <s:hidden name="stringName" value="%{stringName}"/> But it did not work.
Could someone please provide any solution to this behaviour ?
EDIT :
Action class :
public class Test extends ActionSupport implements
ParameterAware, SessionAware {
private String stringName;
private ObjectA objectName;
public String getStringName() {
return stringName;
}
public void setStringName(String s) {
this.stringName = s;
}
public String getObjectName() {
return objectName;
}
public void setObjectName(ObjectA oa) {
this.objectName = oa;
}
public String execute() throws Exception {
objectName = POPULATE_THIS_OBJECT_SOMEHOW
this.stringName = objectName.getStringName();
return SUCCESS;
}
}
ObjectA :
public class ObjectA {
private String stringName;
public String getStringName() {
return stringName;
}
public void setStringName(String s) {
this.stringName = s;
}
}
For example, I have an URL: /test.action?a=1&b=2
Now I want in jsp page use to get only "a=1&b=2" out of the URL, how to do this?
Action Code
public class MyAction extends ActionSupport {
private String a;
private String a;
public String execute() throws Exception {
// do something here
return SUCCESS;
}
public String getA() {
return a;
}
public void setA(final String a) {
this.a= a;
}
public String getB() {
return b;
}
public void setB(final String b) {
this.a= a;
}
}
Using Struts tags:
<s:property value="a"/>
<s:property value="b"/>
Still i am not sure what exactly is your requirement as its not very clear from your question
Just a side note <s:url> This tag is used to create a URL
How to inject IServiceLocator to my class constructor?
When I tried to do this via my config, described above I got an Exception that it could not to create a RequestHandlersFactory class because unity could't find the constructor with serviceLocator and assemblyName.
I got two interfaces
public interface IPublicService
{
[OperationContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
Response Handle(Request request);
}
public interface IRequestHandlersFactory
{
IRequestHandler GetHandler(Type requestType);
IRequestHandler GetHandler<T>()
where T : Request;
IRequestHandler<T, TK> GetHandler<T, TK>()
where T : Request
where TK : Response;
}
and two classes:
public sealed class PublicService: IPublicService
{
private readonly IRequestHandlersFactory _requestHandlersFactory;
public PublicService(IRequestHandlersFactory requestHandlersFactory)
{
_requestHandlersFactory = requestHandlersFactory;
}
public Response Handle(Request request)
{
var handler = _requestHandlersFactory.GetHandler(request.GetType());
return handler.Handle(request);
}
}
public sealed class RequestHandlersFactory : IRequestHandlersFactory
{
private readonly IServiceLocator _serviceLocator;
private RequestHandlersFactory(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
...
}
public RequestHandlersFactory(IServiceLocator serviceLocator, String assemblyName) : this(serviceLocator)
{
AddHandlersFromAssembly(Assembly.Load(assemblyName));
}
public RequestHandlersFactory(IServiceLocator serviceLocator, Assembly assembly) : this(serviceLocator)
{
AddHandlersFromAssembly(assembly);
}
...
}
Now I want to create unity config file:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IPublicService" type="MyAssembly.IPublicService, MyAssembly"/>
<alias alias="PublicService" type="MyAssembly.PublicService, MyAssembly"/>
<alias alias="IRequestHandlersFactory" type="MyAssembly.IRequestHandlersFactory, MyAssembly"/>
<alias alias="RequestHandlersFactory" type="MyAssembly.RequestHandlersFactory, MyAssembly"/>
<container>
<register type="IPublicService" mapTo="PublicService">
<lifetime type="singleton"/>
</register>
<register type="IRequestHandlersFactory" mapTo="RequestHandlersFactory">
<lifetime type="singleton"/>
<constructor>
<param name="assemblyName">
<value value="MyAssemblyWithHandlers" />
</param>
<param name="serviceLocator" dependencyName="WcfServiceLocator" dependencyType="Microsoft.Practices.ServiceLocation.IServiceLocator, Microsoft.Practices.ServiceLocation"/>
</constructor>
</register>
</container>
My config code:
var container = new UnityContainer();
//configure container
var unitySection = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
var serviceLocator = new UnityServiceLocator(container );
container.RegisterInstance<IServiceLocator>("WcfServiceLocator", serviceLocator, new ContainerControlledLifetimeManager());
unitySection.Configure(container);
Try swapping the order of the constructor parameters in the config file so they line up with the actual parameter list in the class.