While migrating Struts 1 to Struts 2, the FormTag class in Struts 2 is missing a getOnsubmit method - struts2

I am doing a Struts 1 to Struts 2 migration. We have Struts 1 code that has extended and customised the org.apache.struts.taglib.html.FormTag. Did some search and found that the org.apache.struts2.views.jsp.ui.FormTag is the equivalent in Struts2.
My current Struts 1 code modifies the onsubmit variable of the FormTag by calling the setOnsubmit(), but it does that by first doing a getOnsubmit() like below.
if (this.getOnsubmit() == null) {
this.setOnsubmit(subCmd + subCmdEnd);
}
else {
this.setOnsubmit(subCmd + this.getOnsubmit() + subCmdEnd);
}
The Struts 2 class has the setOnsubmit(), but not the getOnsubmit(). Do we have any other option available to read the onsubmit value?

The <s:form> tag belongs to Struts 2 core tag library. So, if you need to use your own tag that extends this one then you should extend org.apache.struts2.views.jsp.ui.FormTag class and provide your own implementation by overriding public methods, and adding additional methods. The onsubmit field has a protected modifyer.
But before doing any changes to the Struts 2 framework ask an advice from qualifyed experts: why do you need to do it? For carrying the old code to the new one? The code that is written for S1 is incompatible with S2.
onsubmit is a HTML attribute of the HTML <form> tag, and it could be set in the any other ways on the server, i.e. using OGNL, or on the client using JavaScript.
Also when migrating from Struts1 to Struts 2 you should read Struts 1 to Struts 2 migration strategy.

Related

Struts 2.x migration - How to achieve same URL pattern as Struts 1.x

Currently I am working in Struts migration task from 1.x to 2.x. The major problem I am facing is that change in URL pattern.
In Struts 1, we use url pattern as below.
Note: multiple methods resides in each action class
https://<host-name>/xxx.do?method=begin
After struts 2, we are following below url pattern
https://<host-name>/xxx_begin.action
struts.xml:(used wildcard mapping)
<action name="xxx_*" method ="{1}" class = "foo.Myaction"><result name="success"> myjsp.jsp</result></action>
Question:
Is there any way to achieve the same url pattern as mentioned for Struts 1 in Struts 2?
Since its very big project, it is very complicated to update each and every place where the invocation happens.
I have searched through many sources and found, it is easy to configure .action extension to .do extension by simply adding the below config in struts.xml
<constant name="struts.action.extension" value="do"/>
But how to achieve the method invocation as same as Struts 1.
If there is solution, also please mention how to add the action mapping in struts.xml?
Struts actions are mapped using the ActionMapper. You can use different action mapper class configured to the application. The action mapper used by default is not able to map URLs to actions the same way you did in Struts 1. Some action mappers are available via plugins but it's not possible to map parameters to the action. Only action name and namespace are mapped.
It is important that before you write your own action mapper to understand What is the role of the action mapper in Struts 2 and its scope.
There's also special parameter used by DMI, which is using a method prefix parameter name. If you find a way how to change the parameter to use its value as a name and add a method: prefix. The documentation said that a method prefix can be somehow overridden.
With method-prefix, instead of calling baz action’s execute() method (by default if it isn’t overridden in struts.xml to be something else), the baz action’s anotherMethod() will be called.
Struts 2 can be extended via providing a custom action mapper.

How action mapping is done with struts with the help of struts-config.xml?

I would like to know how the action mapping is done by struts reading struts-config.xml file.
Will this differ between Struts1 and Struts2 - the way in which the action mapping is done?
Help me know about it.
In Struts1 action mapping is defined by the struts-config.xml action tag.
In Struts2 action mapping is defined by the struts.xml action tag.
Note, that action mapping implementation in Struts2 vary on which plugin provides it. The plugins also provide their own action configs.

ASP.NET MVC Validation add class to containing div

I'm using bootstrap CSS form styles, When a textbox gets a validation error message, I need to put the class "error" on the containg . How can I do this?
Problem is, all the validations fire on ajax before submitting the form, except for my custom validators which only fire on post. So need to make sure it happens 4 both scenarios.
http://twitter.github.com/bootstrap/base-css.html#forms
Inside the onError function in jquery.validate.unobtrusive, just add the .addClass("error") line like this:
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false;
container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);
container.parents(".field-encapsulator:first").addClass("error");
if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}
ASP.NET MVC adds the field-validation-error class to the error message element, and input-validation-error to form controls, both on the server-side and client-side via javascript. There's no containing element, depending on your code the form control and its label may or may not be under the same containing element. And, even if they do, MVC will set the mentioned classes to the form control and error message element and not the containing element.
Also, when you autogenerate a form using Html.EditorForModel() the generated markup is like this:
<div class="editor-label"><label for="foo">Foo</label></div>
<div class="editor-field"><input name="foo"/></div>
There's no containing element that could map to the control-group class on Twitter Bootstrap. You could change this template by adding an EditorTemplates/Object.cshtml template.
I'd suggest you adapt Twitter Bootstrap to ASP.NET MVC and not the other way around.
As described in some of the answers at How to add a 'submitHandler' function when using jQuery Unobtrusive Validation?, the settings can be accessed by $("form").data("validator").settings.
And you can then set any valid/invalid class you like:
var settings = $("form").data("validator").settings;
settings.errorClass += " is-invalid";
settings.validClass += " is-valid";

JSF2 + IceFaces 2 - Retrieve UIComponent from ViewRoot

I've got hard time resolving the following. My problem is quite simple : I would like to highlight in red the forms fields that triggered validation errors. The error messages are placed correctly in the FacesContext using a context.addMessage(...) line.
I'd like my system to be generic. All form fields having a message attached are automatically highlighted.
I've found on this site a link to this excellent article :
http://www.jroller.com/mert/entry/how_to_find_a_uicomponent
With it, I did implement a PhaseListener for the RENDER_RESPONSE phase, which do the following :
#Override
public void beforePhase(PhaseEvent event) {
// get context
FacesContext context = event.getFacesContext();
// iterate on all the clientIds which have messages
Iterator<String> clientIdsWithMessages = context.getClientIdsWithMessages();
while (clientIdsWithMessages.hasNext()) {
// get the clientId for the field component
String clientIdWithMessage = clientIdsWithMessages.next();
// split on ":"
String[] splitted = clientIdWithMessage.split(":");
UIComponent component = findComponentInRoot(splitted[splitted.length - 1]);
if (component != null) {
Map<String, Object> attributes = component.getAttributes();
if (attributes.containsKey("style")) {
attributes.remove("style");
}
attributes.put("style", "background-color: #FFE1E1;");
}
}
}
This perform perfectly well for almost all my usage.
Now, where it becomes a bit tricky, is that some of my forms have such code :
<ice:dataTable id="revisionDocuments" value="#{agendaBean.agenda.revisionsDocuments}" var="revision">
<ice:column>
<ice:inputText value="#{revision.sequenceAdresse}" id="revisionSequenceAdresse" />
</ice:column>
....
The generated form has several lines (one for each object of the revisionsDocuments list), and each element has a unique identifier (clientId) which looks like :
contentForm:revisionDocuments:0:revisionSequenceAdresse
With 0 changed for 1, 2, ... for each iteration.
Consequently, the code provided to search the UIComponent from ViewRoot does not work properly. All forms fields have the same "id". What surprise me more is : they have the same "clientId" in FacesContext too :
contentForm:revisionDocuments:revisionSequenceAdresse
I cannot distinguish, while going through the tree, if I do see the right form field or any of the others.
Does anyone have a hint to solve this ? Or another suggestion to implement the highlight of my fields ? I have to admit, I dont really like my code, I consider dirty to manipulate the viewRoot like I'm doing, but I could not figure out a better solution to have a generic highlight of my fields.
I'm running IceFaces 2.0.2 with JSF-Impl 2.1.1-b04 on JBOss AS 7.0.2.Final.
Thank you in advance for the answers.
Best regards,
Patrick
You should apply this in the client side instead. You've got a collection of client IDs with messages. One of the ways is to pass this information to JavaScript and let it do the job. You can find an example of such a PhaseListener in this article: Set focus and highlight in JSF.
Since JSF 2.0 there is however another way without the need for a PhaseListener. There's a new implicit EL variable, #{component} which refers to the UIComponent instance of the current component. In case of UIInput components, there's an isValid() method. This allows you to do something like:
<h:inputText styleClass="#{component.valid ? '' : 'error'}" />
with this in a CSS file:
.error {
background: #ffe1e1;
}
(yes, you can also do this in a style attribute, but mingling style with markup is a poor practice)
To abstract this away (so that you don't need to repeat it in every input), you can just create a composite component for this, something like <my:input>.
For completeness, here is the solution I finally found to highlight the fields that do have error messages with IceFaces 2.0.2 :
The basic idea is strictly the same than proposed by BalusC on http://balusc.blogspot.com/2007/12/set-focus-in-jsf.html
The piece of code I had to change with IceFaces is the small Javascript call :
<script>
setHighlight('${highlight}');
</script>
I could not find any IceFaces component which is re-rendered at each JS call. I found that placing the script into a panelGroup works most of the time. However, there was a case that did not work :
submitting the form with errors do trigger the JS.
then, re-submitting the form with errors on the same field than previous validation do NOT trigger the JS.
then, re-submitting the form with any error field having no more errors do trigger JS.
then, re-submitting the form with any non-errored field having an error do trigger JS.
For some reason, IceFaces do not render the panelGroup that contains the JS when the set of fields having errors is the same between two calls.
I tried to use the Javascript API with code like Ice.onAsynchronousReceive(), using Prototype library to attach an event to the AJAX completion of the commandButton, but had not much success with it. Some of my tests could run (with errors but did the job) and I could observe similar behavior.
Here is the trick I finally used (ugly but working) :
<ice:panelGroup>
<script type="text/javascript">
var useless = '#{testBean.time}';
setHighlight('${highlight}');
</script>
</ice:panelGroup>
The getTime() function simply return the current timestamp. The value is then always different and trigger the JS execution at any AJAX request.
Sadly, IceFaces do not have the RichFaces useful "oncomplete" attribute, which I do regret highly for this case.
Ugly solution, but funny and working.

Migration from Struts1 to Struts2 [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have my application in Struts1 and I have used Dispatch action in all my actions. Please tell me now how do I Shift to struts 2 and what are the modifications that should be made to change all my actions and form beans.
I will suggest you this document series:
http://www.infoq.com/articles/converting-struts-2-part1
http://www.infoq.com/articles/migrating-struts-2-part2
First link explains the topic and there is an example at second link. I wrote below an explanation taken from there:
Configuring the framework
The first, and most important configuration, is the one that enables the web application framework within the servlet containers web.xml file.
The configuration that everyone should be familiar with for Struts is:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
For Struts2 there are very few changes. The most significant is that the dispatcher has been changed from a servlet to a servlet filter. The configuration is just as easy as for a servlet, and shown here:
<filter>
<filter-name>webwork</filter-name>
<filter-class>
org.apache.struts.action2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Deconstructing the Actions
In the request walk-through we spoke about some of the differences between Struts and Struts2 from a high level. Let's take it a step deeper now, and look at the differences between the structures of the actions in each framework.
Let's first review the general structure of the Struts action. The general form of the Struts action looks like this:
public class MyAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// do the work
return (mapping.findForward("success"));
}
}
When implementing a Struts action, you need to be aware of the following items:
All actions have to extend the Action base class.
All actions have to be thread-safe, as only a single action instance is created.
Because the actions have to be thread-safe, all the objects that may be needed in the processing of the action are passed in the method signature.
The name of the method that is invoked for the processing of the action is "execute" (there is a DispatchAction class available in Struts which can re-route the method to be executed to another method in the same action, however the initial entry point from the framework into the action is still the "execute" method).
An ActionForward result is returned using a method from the ActionMapping class, most commonly via the "findForward" method call.
In contrast, the Struts2 action provides a much simpler implementation. Here's what it looks like:
public class MyAction {
public String execute() throws Exception {
// do the work
return "success";
}
}
The first thing you may have noticed is that the action doesn't extend any classes or interfaces. In fact, it goes further than this. By convention, the method invoked in the processing of an action is the "execute" method - but it doesn't have to be. Any method that follows the method signature public String methodName() can be invoked through configuration.
Finally, and perhaps the most revolutionary difference from the original Struts implementation, is that the method invoked in the processing of an action (the "execute" method) has no parameter. So how do you get access to the objects that you need to work with? The answer lies in the "inversion of control" or "dependency injection" pattern (for more information Martin Fowler has an informative article at http://www.martinfowler.com/articles/injection.html). The Spring Framework has popularized this pattern, however, the predecessor to Struts2 (WebWork) started using the pattern around the same time.
You may use dynamic method invocation to vaguely-mimic the old DispatchAction-style "pass in the method name" functionality (or you could write an interceptor that used a parameter to do much the same thing).
There are no "form beans" per se in Struts 2, although you can implement ModelDriven (some docs) and it sort-of works like a form bean.
All JSPs will need to be re-written, but only if you're using the Struts 1 tags. If you used only JSTL tags, you may not need to, it'd depend.
The link provided by Ischin is a good place to start getting more details.
For the Struts 2.x: Make the dispatcher action filter as *.action
For the struts 1.x: Make the action filter as *.do .

Resources