Struts2 type conversion Checkboxlist - struts2

i have a index.jsp home page which has following checkboxlist to select the favorite fruit:
friuts that i like : <s:checkboxlist name="myFruits" list="{'apple','mango','orange'}"/>
in the actionssupport file, i have used the 'myFruits' String type. :
public class Action1 extends ActionSupport
{
String myFruits;
public String getMyFruits() {
return myFruits;
}
public void setMyFruits(String myFruits) {
this.myFruits = myFruits;
}
public String execute()
{
return "success";
}
}
And the results.jsp which reads the selected values :
my favorite fruit is:<br>
<s:property value="myFruits"/>
the output comes up correctly.
my favorite fruit is:
apple, mango
But i am not able to understand how the multiple values selected for example apple and mango are getting stored in valuestack with String myFruit type. Shouldn't this be a List or an array?
Why the above code works fine with just a String type to hold multiple String names?

But I am not able to understand how the multiple values selected for example apple and mango are getting stored in valuestack with String myFruit type. Shouldn't this be a List or an array?
You have a string property with the name myFruits and parameters with the same name. Struts is doing the best to populate that property, and if the parameter has multiple values but a property is a single string type, they could be converted as string with values separated by comma.
On the other hand if you have an array or list property type, the values will be set as array or list.

Related

Ho to use a custom mapper with mapstruct with nested values and conditional values

I am trying to map one object to another using mapstrut and currently facing some challenges on how to use it for some cases.
public class TargetOrderDto {
String id;
String preferedItem;
List<Item> items;
String status;
Address address;
}
public class Item {
String id;
String name;
}
public abstract class TargetOrderMapper {
#Autowired
private StatusRepository statusRepository;
#Mappings({
#Mapping(target = "id", source = "reference"),
#Mapping(target = "preferedItem", source = ""), // Here I need to loop through these values checking for a single value with a specific tag
#Mapping(target = "items", source = "items"), // List of objects to another list of different data types.
#Mapping(target = "status", source = "remoteStatus") // may need to extract a value from a repository
})
abstract OrderDto toTargetOrderDto(RemoteOrder remoteOrder);
}
// Remote Data
public class RemoteOrder {
String reference;
List<Item> items;
String remoteStatus;
}
public class RemoteItem {
String id;
String flag;
String description;
}
These are the current scenarios that I have failed to get my head around (maybe I am mapping a complex object).
preferedItem :
for this, I need to loop though the items in the order and identify the item with a specific flag. (if it matches then I take that value else I use null)
items :
I need to convert this to a list of 2 different lists; List from List, all have different mapping rules of their own.
remoteStatus :
This one is abit more tricky, I need to extract the status from remoteOrder then lookit up in the db using the statusRepository for an alternate mapped value in db.
any help is highly appreciated.
You can't do business logic with MapStruct. So keep mappings simple and define your own methods were it comes to conditional mappings in list. Note: you can write your own method and MapStruct will select it. Also, from this own implementation you can refer to MapStruct methods again.
public abstract class TargetOrderMapper {
#Autowired
private StatusRepository statusRepository;
#Mappings({
#Mapping(target = "id", source = "reference"),
#Mapping(target = "preferedItem", source = ""), // Here I need to loop through these values checking for a single value with a specific tag
#Mapping(target = "items", source = "items"), // List of objects to another list of different data types.
#Mapping(target = "status", source = "remoteStatus") // may need to extract a value from a repository
})
abstract OrderDto toTargetOrderDto(RemoteOrder remoteOrder);
protected List<Item> toItemList(List<Item> items) {
// do what ever you want..
// and call toItem during iterating.
}
protected abstract Item toItem(Item item);
}
The same goes for status. I added a FAQ entry some time ago about list (mainly about updating, but I guess the same applies here).
About lookups, you can use #MappingContext to pass down a context that contains the logic to access a DB. See here

Model being passed instead of parameter to partial view

I've created a partial view named "_ColorWheel.cshtml" which a string that holds the HEX value of the color.
This is the base model
public class PageComponentModel
{
// .....
public string BgColorVal { get; set; }
}
This model inherits PageComponentModel
public class OneColumnComponentModel: PageComponentModel
{
// ....
}
On their respective views, I use the same line #Html.Partial("_ColorWheel",Model.BgColorVal) to create the control. The view of OneColumnComponentModel works well, but PageComponentModel's throws
The model item passed into the dictionary is of type '.....Model.PageComponentModel', but this dictionary requires a model item of type 'System.String'.
I've tried multiple times to copy and paste the line just in case of typos or whatnot. Setting a breakpoint in razor shows that BgColorVal is string and has the correct value.

Can a Post method take parameters from the Query String?

I was looking at https://stackoverflow.com/a/15873977 but it didn't work for me.
If my Post method has a parameter named Message (an object of my own class), and I do not apply the [FromBody] attribute to it, is it possible to pass the parameter Message, json serialized and urlEncoded, on the query string instead of in the Post body?
I tried passing ?Message=%7B+%22Sender%22%3A...+%7D (which if decoded would be Message={ "Sender":... }) but the Message parameter is still received as null in the method.
Should the query string key be Message, the name of the parameter, or the class name of the parameter or something else?
If you have a model Foo:
public class Foo
{
public string Bar { get; set; }
public int Baz { get; set; }
}
And you want to bind this from the query string, then you must address the individual properties:
?Bar=qux&Baz=42
And annotate that the model must be bound from the query string:
public void Bar([FromUri]Foo foo)
{
}
If you really want to send JSON into your action method and not a model, simply bind to a string instead of a model. You can then do whatever you want with the JSON string inside your action method.

Shielding nullable domain properties with ViewModel

I am using Entity Framework 4.0, and making use of POCO objects. When I populate POCO objects from the DB, I translate property values to my own Domain objects, which we can call my Model.
Necessarily, whether or not the fields of my Model are Nullable depends on whether the value it maps to in the database comes from a NULL or NOT NULL column. I won't go into detail, but the values must be nullable in the DB, because a user can partially save a draft of the object before publishing it to the public. That being the case, I have several fields that are nullable. So let's say my model looks like:
public class MyModel
{
public int? Field1 {get; set; }
public DateTime? Field2 {get; set; }
public int Field3 {get; set; }
}
If I use this Model in my View, complete with nullable fields, I begin receiving errors that tell me I cannot use nullable properties as values in various places, like HTML helpers, etc. I could say something like if (Model.MyBoolField.HasValue && Model.MyBoolField.Value) { // etc }, but that feels bulky for a view.
I considered creating a ViewModel object that inherits from my original domain object and has new, non-nullable versions of my nullable fields that return an appropriate value if the base version is null. So something like:
public class MyViewModel : MyModel
{
public new int Field1
{
get { return base.Field1 ?? 7; }
}
public new DateTime Field2
{
get { return base.Field2 ?? DateTime.Now; }
}
}
My problem with this is that I don't always know a good "default" value to display. What if I threw an exception in the View Model's getter when the base value is null? Is that poor practice?
I'm basically looking for a best practice on how to handle nullable fields in a model, particularly when displaying in a View.
If you just need to display these fields in a View, you don't need to specify or check whether is has a value or not.
Using Model.Field1 in your View file is enough. It will simple not display anything, and it won't throw an exception. You can always use ?? to set a default when it makes sense.
#(Model.Field1 ?? "There is nothing to see here")
In most of the cases I use the "For" helpers, which seem OK with Nullable values (PublishedCount is a nullable property):
#Html.TextBoxFor(m => m.BillPull.PublishedCount, new { id="txtPublishedCount" })
#Html.ValidationMessageFor(m => m.BillPull.PublishedCount)
When I need to use just TextBox, I use the GetValueOrDefault method, with whatever default value the framework provides:
#Html.TextBox("BillPull.AutoPublishDate", Model.BillPull.AutoPublishDate.GetValueOrDefault().ToString(dateFormat), new { id = "dtpAutoPublishDate" })
#Html.ValidationMessageFor(m => m.BillPull.AutoPublishDate)

Struts2 using Map in select tag

You can easily use a List in struts2 select tag, but is there a way to use Map in tag?? If it is possible please provide a sample code...
thanx !
In my action class
public class MyAction extends ActionSupport {
private Map<String, String> map;
public String execute() throws Exception {
map = new HashMap<String, String>();
map.put("abc", "abc");
map.put("xyz", "xyz");
return SUCCESS;
}
}
For the jsp mapped to success, use some thing like this
<s:select list = "map" name = "name" label = "Name" headerKey="" headerValue = "Enter Value"/>
It depends on what are you trying to do. Lacking details, I can only point you to the docs : the list attribute of the select tag is an ...
Iterable source to populate from. If
the list is a Map (key, value), the
Map key will become the option 'value'
parameter and the Map value will
become the option body.
Below in the same doc there is an example with a (literal, inline) map (Months).

Resources