First of all I'm newbie in Struts.
I've a class:
public class Articulo {
private int codigo;
private String descripcion;
public int getCodigo() {
return codigo;
}
public void setCodigo(int codigo) {
this.codigo = codigo;
}
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
}
which is populated with values in a dispatcher. In the dispatcher I've
private Articulo articulo;
.......
public Articulo getArticulo() {
return articulo;
}
public void setArticulo(Articulo articulo) {
this.articulo = articulo;
}
There is also a JSP with
<s:property value="articulo"/>
which read ok the articulo. Also works articulo
<s:property value="articulo.codigo"/>
But now I want from that jsp forward the entire object articulo to another action.
I can do
<s:hidden name="articulo.codigo" value="%{articulo.codigo}"/>
<s:hidden name="articulo.descripcion" value="%{articulo.descripcion}"/>
and that works fine, but is there anyway to do something like
<s:hidden name="articulo" value="%{articulo}"/>
So, is there anyway to get the object from JSP without setting all the properties of it?
there are 2 points:
Problem: you can't transfer object using <s:hidden />, all the parameter, what are transfered with HTTP should be string. Since you cannot convert this object to String, you can't transfer it using HTTP either.
Solution: You can put your object into session, so that you can access it anytime you want. here is an EXAMPLE
Yes, you can transfer object in two ways either by parameter or store it in session and access it whenever you need it.
<jsp:forward page="URL" >
<jsp:param name="ParamName1" value="YourObject" />
</jsp:forward>
Visit here for more detail.
http://www.gulland.com/courses/jsp/actions/forward
Keeping the object information in sessions is usually the preferred method.
But an alternative option is to create your own Type Converter.
Create a type converter by extending StrutsTypeConverter. The
Converter's role is to convert a String to an Object and an Object to
a String.
By doing so, you could so something like <s:hidden name="articulo" value="%{articulo}"/>
Keep in mind this method is insecure as the object values will be printed out as String in the hidden tag and can be seen through the browser.
But the advantage is that this method works across different sessions if you have a need for such a thing.
Related
I have a question regarding Thymeleaf and Spring Boot. I'm creating a form wizard and I would like to have the same object passed between multiple controllers, so that the object (SimpleCharacter) stores each time the value from each page.
What I have right now is, that with each endpoint, I get a new object created that "forgets" what I wanted to store from the previous page. How can I achieve that to have the same instance of the object passed between endpoints and in the end fully completed object with fields from each previous endpoint?
private static final String CHARACTER = "character";
#GetMapping(value = "/new-char/01_race")
public String showCharWizRace(Model model) {
CharacterDto character = new SimpleCharacter();
model.addAttribute(CHARACTER, character);
return "new-char/01_race";
}
#PostMapping(value = "/new-char/02_class")
public String showCharWizClass(Model model, #ModelAttribute CharacterDto character) {
model.addAttribute(CHARACTER, character);
model.addAttribute("classes", charClassService.findAll());
return "new-char/02_class";
}
#PostMapping(value = "/new-char/03_attributes")
public String showCharWizAttributes(Model model, #ModelAttribute CharacterDto character) {
model.addAttribute(CHARACTER, character);
return "new-char/03_attributes";
}
Thank you very much for all valuable hints and help. I've searched the Web, but couldn't find anything useful to point me in the right direction.
EDIT: But if you make CharacterDto have more fields for example race, class, attributes and use each time only one page (one form) to provide one field, spring "forgets" the other property when opening the next form. For example: 1st page: race is set, 2nd page (no race field existing here) class is set but in this place the previously set race had been already forgotten.
CharacterDto fields, that should be filled step by step on each page:
private String race;
private String charClass;
private int strength;
private int endurance;
private int dexterity;
private int charisma;
private int intelligence;
private int perception;
private String name;
private String surname;
private String description;
private String title;
private String avatar;
First, your character field are inside a spring form?
If yes, you also could to store your variable in a hidden field and pass this by #RequestParam.
Follow a example:
<input th:field="*{character}" name="character"/>
And in your controller method add a request parameter variable
showCharWizClass(#RequestParam(value = "character", required = false) String character, otherVariables){}
If it doesn't work, you also try to use something like a template strategy with session.
Putting your variable in a session scope, changing the variable with each request and removing it on last access.
Here a good link about access data from templates:
https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html
UPDATE
You need to combine Model and Session Attributes in your workflow pages.
In your controller add a SessionAttribute pointing to the DTO that is using, like this:
#Controller
#SessionAttributes("character")
public class WizardController { ..
And when you have finished your flow, you can end session attributes this way.
#GetMapping(value = "/new-char/04_clear")
public String clearSession(SessionStatus sessionStatus) {
sessionStatus.setComplete();
return "new-char/04_clear";
}
If you look at my example code I add a new page to clean session and restart a form with a default DTO values.
I have a thymeleaf form and spring boot back-end. I have a model class which has defiened it's getters and setters little bit deferent name. so when Im going to take that model and get its fields as form input fields thymeleaf can not recognised them as fields.
here is my modal,
public class scDto {
private Integer region;
private boolean isAmt;
public scDto() {
}
public Integer getRegion() {
return this.region;
}
public void setRegion(Integer region) {
this.region = region;
}
public boolean isAmt() {
return this.isAmt;
}
public void setAmt(boolean amt) {
this.isAmt = amt;
}
here is my form input field,
<input type="text" th:field="*{sc.isAmt}"/>
here is the error,
Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (price:331)
Form is working well for region field. but it does not work for Amt field.
Maybe I can fix this if I changed isAmt() get method to getIsAmt(). But I cant change any method name of the modal class because that class already compiled and I used it via a jar file. Is there anyway to solve this problem.
(Copied from the comments under the question)
I guess you can try to refer to this variable using the {sc.amt}.
More information about the javabeans notation you can read here: stackoverflow.com/a/17066599/7629196
Seeing your DTO it has only 2 fields
public class scDto {
private Integer region;
private boolean isAmt;
public boolean isAmt() {
return this.isAmt;
}
...
}
As per convention
For method name like this
boolean isXyz()
you will read it like xyz
So this line
<input type="text" th:field="*{sc.isAmt}"/>
should be
<input type="text" th:field="*{sc.amt}"/>
Credit also goes to Ruslan K for mentioning this in Comment.
Just adding to add more clarity.
I have a Stripes form using an Action bean.
I can store the data without any problem out of the form, but I did not find out how to prepopulate the form's data.
I have simplified my example to show what's not working.
My code under #Before is without any effect: the data dont go into the form.
How should I manage this approach?
myform.jsp:
...
<stripes:form beanclass="UserActionBean">
...
<stripes:text name="user" />
<stripes:submit name="store" value="Save" />
...
</stripes:form>
...
ActionBean:
public class UserActionBean implements ActionBean {
private String user;
#Before
public void init() {
user = "myuser";
}
#DefaultHandler
public Resolution store() {
...
}
}
You will need public getters and setters for Stripes to be able to read the value.
Although usually I would use the #DefaultHandler for the get, and then create a new handler for the save e.g. #HandlesEvent(value = "save") public Resolution save () {...
This might be crude, but I used a getter like Scary Wombat said and initialized the variable in the ActionBean. Or you could set its value in your handler that does the initial page display.
#Validate(required = true, on = {
"proceed"
})
private String tumblrUrl= "xyz.tumblr.com";
...
public String getTumblrUrl() {
return this.tumblrUrl;
}
public void setTumblrUrl(final String tumblrUrl) {
this.tumblrUrl = tumblrUrl;
}
Hy guys, I've turning around a problem using Struts2.
Basically I've a form that the user can submit filling different fields. I would like to populate conditionally the right object with the properties insert by the user.
So for example, if the user fill the form in a intermediary way I would like to use the properties for to create an Intermediary object, instead if the user fill the request in entity way, i'll use the properties for to create the Entity object, ecc...
These object share the same interface Request.
Is there any way to use polimorphically properties for to create Intermediary or Entity object?
Suppose this is my two POJO:
public class Intermediary implements Request{
private String name;
private String surname;
private String code;
private String FiscalCode;
private String address;
...
/*Getters and setters */
....
}
public class Entity implements Request{
private String name;
private String surname;
private String code;
....
/*Getters and setters */
....
}
This could be my form into the jsp page:
<s:form action="fillRequest" id="formRichiesta" name="formRichiesta" method="post">
<s:radio id="tipoRichiedente" name="tipoRichiedente" list="richiedenti">
<label>Name</label><s:textfield name="name"/>
<label>Surname</label><s:textfield name="surname"/>
<label>code</label><s:textfield name="code"/>
<label>Adress</label><s:textfield name="adress"/>
<label>Fiscal Code</label><s:textfield name="fiscalCode"/>
</s:form>
<s:submit>
Basically my problem is that I can discover the kind of request the the user trying to fill only ofter submission and watching at the radiobutton state.
Is there any way to mapping the properties into the right object directly instead of creating one big object with all the form properties and then create the right implementation? for to map properties could I use the interface reference?
For example image my action:
public class RequestAction {
private Request request;
....
}
So in my jsp could I use:
<label>Name</label><s:textfield name="request.name"/>
Thanks in advance.
How the data transfer from the action class to Jsp page in struts2.
Is any kind of stack is build inside the action class before its transfer its control to the jsp page , or there is something other mechanism is used for that.
Anshul,
You are some what correct in your implementation.For Struts2 we can see it in following manners
ValueStack
OGNL
Value stack is a virtual stack in Struts2 framework and a central place where all the data related to request processing will be placed by the Framework.In Struts2 Actions are also treated as a data carrier, so what exactly is happening is when the action done its work it is being placed on the top of value stack.
Lets we have something like this in Action
public class MyAction extends ActionSupport{
private String firstname;
private String lastname;
public void setFirstName(firstname){
this.firstname=firstname
}
public void setLastName(lastname){
this.lastname=lastname
}
public String getFirstName(){
return firstname;
}
public String geLastName(){
return lastname;
}
public String execute() throws Exception{
//action logic filling first name and last name from database etc.
return SUCCESS;
}
}
now when action will return after the logic framework will place action instance on the top of value stack and firstname and lastname will be on the top of it.
so now when we try to access these values in jsp something like
<s:textfield name="firstname" value= "%{firstname}"/>
here (%{firstname}) OGNL will come in to place and it will try to see if there is a property in the value stack with name firstname,since action is on the top of value stack and it has property name firstname in it so OGNL will find it.
i hope this will help you