I'm a beginner with portlets, and I don't understand the difference between request.setAttribute and response.setRenderParameter (for an action). Both save an attribute into the request and allow to access to it after. I think specially about transmission between a processAction and the render which is just after the action method.
I know that with setRenderParameter we cannot "stock" a complex object, but if I just want to transfer a String which one should I use?
In which case should we use the setRenderParameter method or the setAttribute method ?
Well, one sets an attribute on a request. The other sets a parameter on the response. They are different objects, obviously.
response.setRenderParameter is of use if you wish to call different render methods based on your action. For example, imagine your action method sends an email, and you want to show the user a different view on success and failure. In this case, you would do something like this in your ActionMapping
if(sentOK){
response.setRenderParameter("result", "success");
}else{
response.setRenderParameter("result", "fail");
}
And then have two RenderMapping methods:
#RenderMapping(params = "result=success")
public String success(){
#RenderMapping(params = "result=fail")
public String fail(){
Related
In the Struts documentation, it says:
Another common workflow stategy is to first render a page using an alternate method, like input and then have it submit back to the default execute method.
https://struts.apache.org/core-developers/action-configuration.html#post-back-default
How to do it using annotation only? It seems that only the execute() method is called.
In the documentation it's said to render a page can be used an alternate method like input. This means that when you submit a form on the page it can return back with the input result. Usually it happens automatically during validation process if the validation fails or it hasErrors. Then you can submit the form back to the default action's execute method. You don't need to specify a method in the action configuration. Also if you didn't specify the action attribute in the form tag then the same action will execute which was used to render a page.
Configuring actions you can use the same page for success result when rendering a page using GET method and input when POST method is requested.
To use annotations to configure actions mapping you can use a Convention Plugin.
Also note, to map a class method to the action you should put #Action annotation directly on this method rather than on the class.
More detailed explanation and documentation you can find here.
#Namespace("/")
public class ProductAction extends ActionSupport {
public String execute() {
return SUCCESS;
}
#Action(value="product",
results=#Result(location="/product-list.jsp")
)
public String search() {
return SUCCESS;
}
}
Notice, that the method execute is not mapped, so it will not execute. If you need that method execute you should create mapping to it. For this purpose you could place annotation on class or on method execute.
I created a custom module that add a field to the registration form and account modification.
The problem is that it is added to all websites. I only need it on a specific website.
This is the module I created:
https://github.com/stfn97/magento2-custom-registration-field
If you want to add logic to a template (for example, render it only if certain "requirements" are met) you will use either a block or a view model.
In this case I recommend using a block because the Magento\Framework\View\Element\Template class contains a _toHtml() method which you can override to either render or not render your template.
class MyBlockClass extends Template {
public function _toHtml() {
if (what you want your condition to be) {
return '';
}
return parent::_toHtml();
}
}
you can use a ternary operator for this but I thought the above notation would be more obvious
Magento\Store\Model\StoreManagerInterface can then be used to get the store the customer is currently in and thus the website as well.
If you call Magento\Store\Model\StoreManagerInterface::getStore() without an argument (store id) it will return the store the customer is currently in.
Because the above method returns a Magento\Store\Api\Data\StoreInterface the Magento\Store\Api\Data\StoreInterface::getWebsiteId() can then be used to get the website associated with the store the customer is currently in.
If you want more information about the website you'll need a Magento\Store\Api\Data\WebsiteInterface, this you can get by calling Magento\Store\Model\StoreManagerInterface::getWebsite($websiteId) with the website id returned by the previously mentioned method.
Combining all this you can determine the website the customer is currently in and use that to either render or not render the template using the Magento\Framework\View\Element\Template::_toHtml() method.
I am currently programming a REST service and a website that mostly uses this REST service.
Model:
public class User {
private String realname;
private String username;
private String emailAddress;
private String password;
private Role role;
..
}
View:
One form to update
realname
email address
username
Another form to update the role
And a third form to change the password
.
Focussing on the first view, which pattern would be a good practice?
PUT /user/{userId}
imho not because the form contains only partial data (not role, not password). So it cannot send a whole user object.
PATCH /user/{userId}
may be ok. Is a good way to implement it like:
1) read current user entity
2)
if(source.getRealname() != null) // Check if field was set (partial update)
dest.setRealname(source.getRealname());
.. for all available fields
3) save dest
POST /user/{userId}/generalInformation
as summary for realname, email, username
.
Thank you!
One problem with this approach is that user cannot nullify optional fields since code is not applying the value if (input is empty and value) is null.
This might be ok for password or other required entity field but for example if you have an optional Note field then the user cannot "clean" the field.
Also, if you are using a plain FORM you cannot use PATCH method, only GET or POST.
If you are using Ajax you might be interested in JSON Merge Patch (easier) and/or JavaScript Object Notation (JSON) Patch (most complete); for an overview of the problems that one can find in partial updates and in using PATCH see also this page.
A point is that a form can only send empty or filled value, while a JSON object property can have three states: value (update), null (set null) and no-property (ignore).
An implementation I used with success is ZJSONPATCH
Focussing on the first view, which pattern would be a good practice?
My suggestion starts from a simple idea: how would you do this as web pages in HTML?
You probably start from a page that offers a view of the user, with hyperlinks like "Update profile", "Update role", "Change password". Clicking on update profile would load an html form, maybe with a bunch of default values already filled in. The operator would make changes, then submit the form, which would send a message to an endpoint that knows how to decode the message body and update the model.
The first two steps are "safe" -- the operator isn't proposing any changes. In the last step, the operator is proposing a change, so safe methods would not be appropriate.
HTML, as a hypermedia format, is limited to two methods (GET, POST), so we might see the browser do something like
GET /user/:id
GET /forms/updateGeneralInformation?:id
POST /updates/generalInformation/:id
There are lots of different spellings you can use, depending on how to prefer to organize your resources. The browser doesn't care, because it's just following links.
You have that same flexibility in your API. The first trick in the kit should always be "can I solve this with a new resource?".
Ian S Robinson observed: specialization and innovation depend on an open set. If you restrict yourself to a closed vocabulary of HTTP methods, then the open set you need to innovate needs to lie elsewhere: the RESTful approach is to use an open set of resources.
Update of a profile really does sound like an operation that should be idempotent, so you'd like to use PUT if you can. Is there anything wrong with:
GET /user/:id/generalInformation
PUT /user/:id/generalInformation
It's a write, it's idempotent, it's a complete replacement of the generalInformation resource, so the HTTP spec is happy.
Yes, changing the current representation of multiple resources with a single request is valid HTTP. In fact, this is one of the approaches described by RFC 7231
Partial content updates are possible by targeting a separately identified resource with state that overlaps a portion of the larger resource
If you don't like supporting multiple views of a resource and supporting PUT on each, you can apply the same heuristic ("add more resources") by introducing a command queue to handle changes to the underlying model.
GET /user/:id/generalInformation
PUT /changeRequests/:uuid
Up to you whether you want to represent all change requests as entries in the same collection, or having specialized collections of change requests for subsets of operations. Tomato, tomahto.
I was looking for a way to identify Struts 2 actions which are of type 'Redirect/Forward' in Interceptor, so that I can add some common code for that particular type of Action.
Is there any way in Struts2 to find what type of Action it is?
Thanks in advance.
There is nothing called as RedirectAction or ForwardAction, what you need it Redirect Result Type.
In your interceptor you have an instance of ActionInvocation passes to your intercept method, you can get the result from ActionInvocation object and then check as per your use case. Different Results are listed here
public String intercept(ActionInvocation actionInvocation) {
//After invoking the action you can get the result of from ActionInvocation.
Result result = actionInvocation.getResult();
//As per your use case you can check against different types.
}
Lets say I have a form with method=POST on my page.
Now this form has some basic form elements like textbox, checkbox, etc
It has action URL as http://example.com/someAction.do?param=value
I do understand that this is actually a contradictory thing to do, but my question is will it work in practice.
So my questions are;
Since the form method is POST and I have a querystring as well in my URL (?param=value)
Will it work correctly? i.e. will I be able to retrieve param=value on my receiving page (someAction.do)
Lets say I use Java/JSP to access the values on server side. So what is the way to get the values on server side ? Is the syntax same to access value of param=value as well as for the form elements like textbox/radio button/checkbox, etc ?
1) YES, you will have access to POST and GET variables since your request will contain both. So you can use $_GET["param_name"] and $_POST["param_name"] accordingly.
2) Using JSP you can use the following code for both:
<%= request.getParameter("param_name") %>
If you're using EL (JSP Expression Language), you can also get them in the following way:
${param.param_name}
EDIT: if the param_name is present in both the request QueryString and POST data, both of them will be returned as an array of values, the first one being the QueryString.
In such scenarios, getParameter("param_name) would return the first one of them (as explained here), however both of them can be read using the getParameterValues("param_name") method in the following way:
String[] values = request.getParameterValues("param_name");
For further info, read here.
Yes. You can retrieve these parameters in your action class.
Just you have to make property of same name (param in your case) with there getters and setters.
Sample Code
private String param;
{... getters and setters ...}
when you will do this, the parameters value (passed via URL) will get saved into the getters of that particular property. and through this, you can do whatever you want with that value.
The POST method just hide the submitted form data from the user. He/she can't see what data has been sent to the server, unless a special tool is used.
The GET method allows anybody to see what data it has. You can easily see the data from the URL (ex. By seeing the key-value pairs in the query string).
In other words it is up to you to show the (maybe unimportant) data to the user by using query string in the form action. For example in a data table filter. To keep the current pagination state, you can use domain.com/path.do?page=3 as an action. And you can hide the other data within the form components, like input, textarea, etc.
Both methods can be catched in the server with the same way. For example in Java, by using request.getParameter("page").