Basic struts1 question: Where is the ActionForm data coming from in Struts 1? - struts

I am maintaining a struts 1 app and need to find the point of the code where (or find out how) the ActionForm object is passed to the Action class, which is the first entry point of the code that I know of, but there is obviously another entry point where data is assembled into an ActionForm object since the Action class entrypoint method signature is this:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
Idea anybody?

The request processor, org.apache.struts.action.RequestProcessor.
The specific method depends on the exact Struts version, e.g., in Struts 1.2 it's the process method, in Struts 1.3 it's the processActionCreate method.
Custom request processors are a well-known extension point in Struts 1; it would probably be worth your time to do some web searching as this is fairly well covered, but again, it's specific to the version.
In addition, request processors are often used in different ways by different extension points (e.g., Tiles and Workflow), which drove some of the changes in Struts 1.3 (ComposableRequestProcessor).

Related

Class sharing between byte-buddy interceptors/advices

I am trying to pass monitoring/tracing information through all my external calls in my java application.
To make it transparent, I'm trying to use byte-buddy but have some troubles getting it to work.
To trace every incoming (http) request, I intercept HttpServlet.service(), extract the token header from the HttpServletRequest and put it in a static ThreadLocal in a class named TokenHolder.
To trace every outgoing (http) request, I intercept HttpURLConnection and add the token header I get from the same ThreadLocal (TokenHolder).
The problem I have is that TokenHolder seems to be initialized twice and my 2 interceptors are not writing-to/reading-from the same ThreadLocal and I can't find a way to do it.
I suppose the problem is that HttpURLConnection lives in the bootclasspath while the servlet API does not.
Bonus question: is it possible to intercept URL.openConnection()? That was my first idea but I never could do it because I suppose the URL class is loaded before the agent (because of URLClassLoader) but I don't know if there are workarounds to that.
Yes, you can register a RedefinitionStrategy where Byte Buddy transforms previously loaded classes. To do so, you do however need to avoid adding methods or fields. This can typically be done by using Advice only.
You are also right that classes need to live on the bootstrap loader. You can inject classes into the bootstrap loader by placing them in a jar and using the designated method in the Instrumentation interface.

Resource or Restlet

I am using Restlet 2.2.1 and building Rest services. As you know, Router is used to attach either Restlet or Resource as target.
Router router = new Router( getContext() );
router.attach("/healthcheck1",HealthCheckResource.class );
router.attach("/healthcheck2", new HealthCheckRestlet() );
Then you can implement your logic in handle()
Wondering which is best one to use? I know Resource has a very definite life cycle (doInit, handle, release ...) and good place to implement one time logic like initialization.
Attach a ServerResource subclass rather than a Restlet instance when feasible, for a couple of reasons:
Resources are the natural way to structure RESTful APIs. When you use the #Get, #Put, etc. annotations on a resource class, you're effectively documenting that part of your RESTful API, and there are tools that can extract that information to create online documentation automatically. If you use a Restlet instance, its behavior in response to GET, PUT, etc. is not immediately apparent. Ironically, using a Restlet makes it easier to write APIs that are not RESTful.
A separate instance of the resource class is created for each request, meaning that an instance is normally confined to a single thread, which simplifies reasoning about thread-safety. In constrast, the same Restlet instance will be used for all handle(...) calls, potentially leading to complicated thread-safety requirements.
Because each request gets its own resource instance, the resource methods might need to appeal to internal services that are passed via the application context or injected into the resource (see this Restlet extension).
Incidentally, your comment about "one time logic like initialization" might be a misunderstanding. The doInit method is called for each instantiated resource (i.e., once per request for that resource), not one time only.
Note that I'm recommending against directly subclassing Restlet as an end target for a resource URL, except maybe for trivial resources. Using subclasses of Restlet is a different matter: Attaching a Filter which wraps a resource is fine.

Ninject: What is MvcModule: GlobalKernelRegistrationModule<OnePerRequestHttpModule>?

I'm seeing Ninject source code, I cannot understand the MvcModule (source code in github).
Why the OnePerRequestHttpModule stand as a generic template type? What does it mean for?
As you undoubtedly know, Ninject.Web.Common defines InRequestScope. This scope is for the activations that should live for the lifetime of a single http request. When an http request is finished, you might want to clear your activation cache for this request, but how do you know that the request has ended?
Well, the usual way of finding out is creating an Http Module and subscribing for the EndRequest event.
Suppose you've done that. Now you need to implement the event handler. In the event handler you want to clear your activation cache for this request, but how does the handler know where this activation cache is located? Ultimately this cache is part of ninject kernel, so if only you could get access to that.
But that's no problem, right? You are the implementer, so why don't you wire up your HttpModule during your kernel set-up?
Unfortunately there are quite a few problems with this approach. First, HttpModules have to be registered during the pre application startup up phase and there is no guarantee that your kernel will be created at that time. More importantly, what if you have multiple kernels? Does each of these going to create a new instance of HTTP Module? Better to avoid that.
So this is what ninject does.
The GlobalKernelRegistration class is almost static class that keeps per domain collection of kernels. It has one instance method - protected void MapKernels(Action<IKernel> action). This method executes and action on every kernel in the list. The kernel lists are kept per registration type, such as OnePerRequestHttpModule.
So what you (as a ninject author) do is derive OnePerRequestHttpModule from GlobalKernelRegistration and then in your implementation of EndRequest event handler you use this.MapKernels to execute your code to clean up the activation cache for the request.
GlobalKernelRegistrationModule class is a simple class that registers your generic type parameter (in your case OnePerRequestHttpModule) and the current kernel in the registry (GlobalKernelRegistration).
When you derive your MvcModule from GlobalKernelRegistrationModule<OnePerRequestHttpModule> this registration happens automatically when your MvcModule is loaded into the kernel.
You also need to make sure that OnePerRequestHttpModule is registered as an Http Module which is usually done in the bootstrap code inside NinjectWebCommon.cs or in NinjectHttpApplication (if the project is not using webapi).
It deactivates objects InRequestScope after the request ended.

When is the ActionForm instantiated?

I am using Struts 1.x for an application.
I want to know when the ActionForm instantiated.
The ActionServlet actually delegates the request processing job to it's RequestProcessor.
When a request arrives, either the doGet or the doPost method of the action servlet is invoked. Any of these method will call the action servlet's process method which inturn calls the request processor's process method. And that's where everything happen, roughly as follows -
Find the ActionMapping for current request.
Get (may be also create) the ActionForm instance.
Populate the form.
Validate the form.
Get (create) the Action instance.
Execute the action.
And finally either forward or redirect.
If you want (or need) to know in detail then you can always take a look at the source code. Followings are the links to the source codes for Struts 1.3.10 (you can also find sources for other versions of struts if that's not your version) -
org.apache.struts.action.ActionServlet
org.apache.struts.action.RequestProcessor

Basic flow of Struts

Well I want to study Struts so I am going to begin with Struts 1,
I would like to know the general flow. What files are required?
Whats the function of struts-config.xml? validation.xml? validation-rules.xml
When you visit your JSP page, and an action gets fired, what happens? What does the Action and Form class do? Which class is called first when an action gets fired.
I just downloaded a sample form, and all these files are confusing at first. I would like to know whats going on to get a better idea of Struts.
You should start with a tutorial on Struts, that will make it easy to understand :D. You can find plenty on the web, especially for Struts 1. Here is a starting point for example.
But just for the sake of it, here is a high view presentation.
First you add the Struts ActionServlet into your web.xml file and you configure it to accept requests that match a certain mapping. For Struts this is *.do (you can have whatever you want for this, *.do is just a convention in the Struts community).
Now, whatever arrives on the server with such a *.do URL pattern is sent to the ActionServlet.
Now, the content of struts-config.xml file comes into play. The ActionServlet is a front controller which just dispatches to other more appropriate resources for specific processing. Those specific resources are the Action classes.
You can have for example a LoginAction that must process requests that arrive on the login.do path. In the struts-config.xml you specify this: everything that comes on the login path must be sent to LoginAction class.
And you can have as many declarations as you want, for path x call XAction, for y call YAction etc etc.
Normally your client submits data to the server, data that he inputs into a HTML form. This data you need to process in your Action class. Now enter ActionForm.
The ActionForm is a bean that the Struts framework fills with the data from the HTML form. Instead of doing request.getParameter("foo") you can work with objects like formBean.getFoo() for example.
Once you do your processing in the Action class using the ActionForm, you then must present the results in some view (by the way, Struts is a MVC framework so you must know a stuff or two about this also).
The views are normally JSP files. When you return from your Action, you specify a "forward" location by name (i.e. to what view to go). Now again the information is in the struts-config.xml file where the name of the view is mapped to a JSP location.
The framework will then forward control to that JSP, the JSP presents the data which is then sent to the client as HTML (the client will no longer need to access JSPs directly - they must be hidden by the Struts framework).
In the new page the client again performs some requests and the process repeats.
Well, that's about as high presentation as it can get. Off course there is more than this, but you will discover them while learning about Struts.
As for the validator-rules.xml and validation.xml, those are used by the Validator framework which you can integrate with Struts by the use of a plugin (Struts has plugins you can use to add new stuff to it) to also add validation to the user's input.
Well, that is about it. You can find plenty of tutorials on the web offering more details but hope helps you get a better start.
Good luck!
When a user submitted a jsp page. that page having (attribute of
)action="login.do". the container will call to web.xml. in that
web.xml there are two sections servlet And servlet mapping
In servlet mapping it find *.do in the url-pattern. if it found to
take the name of servlet. and check the corresponding class. in the
servlet section. that class is ActionServlet.
ActionServlet is the controller of Struts module architecture. in
Action servlet having the service method. in that method we create
RequestPrecessor class instance
Service(req,res) RequestPrecessor rp = new RequestPrecessor();
We call a process method of RequestProcessor class through the
instance rp.process(req,res)
In the request processor class have the process method with the
parameter of req,res. then it has 1 if condition in this class.
that condition return always true. because that is dummy method.
Inside that condition there are 6 steps are processing
Create a action mapping instance in the Struts- Config.xml. it
will keep all details of the action mapping path, value, type
forward, validation=true/false, input
="*.jsp" etc these r created instance
Then it will create Form class instance before it check the name of
action mapping and form name are coincidence or not if it same it
will create form instance
Then it will go to ActionMapping instance the ris mention or not the
validate =true/false if false it will not execute the this step else
it will execute this step.
Then it will create action instance
Next it will take four parameters of execute Method it will return
ActionErrors instance. if it is not empty. it will go to error page
other wise it will got to corresponding page. else if it is empty
if will go further and display corresponding value of page in jsp
view.This is struts flow.
Model
Struts doesn't support Model directly. However, the Struts actions and configuration file provide you ability to implement it by your own.
View
1) Form bean that extends org.apache.struts.action.ActionForm, that is used in two ways at run time:
When a JSP page prepares the related HTML form for display, the JSP
page accesses the bean, which holds values to be placed into the
form. Those values are provided from business logic or from previous
user input.
When user input is returned from a web browser, the bean
validates and holds that input either for use by business logic or
(if validation failed) for subsequent redisplay.
2) Struts tag libraries such as bean, logic, html & tiles plugin
Controller
The Struts action servlet handles runtime events in accordance with a set of rules that are provided at deployment time. Those rules are contained in a Struts configuration file and specify how the servlet responds to every outcome received from the business logic. Changes to the flow of control require changes only to the configuration file.
Struts action extends org.apache.struts.action.Action. At run time, the action servlet is said to "execute actions," which means that the servlet invokes the execute method of each of the instantiated action classes. The object returned from the execute method directs the action servlet as to what action or JSP file to access next.
To facilitate reuse, invoke business logic from the action class rather than including business logic in that class.
See the Struts 1.3 example
For your comparison & reference, here's Struts 2.3 demo