Are Servlet Init parameters accessible in whole servlet container - java

I have this question as i did not find any correct results when searching in Web.
Does Servlet Init Parameters y default accessible in whole container without making any configaration.I mean servlet A has some property x,If another servlet B ,in the same container(may be or may not be in same Application) access it? If so can anyone please show me with an example.
Thanks in Avance.

No, init parameters are servlet-scoped, context-param are application scoped.
There's no other wider scope (e.g. between two applications)

As servlet config, The init parameters of a servlet can only be accessed by that servlet
here is link http://tutorials.jenkov.com/java-servlets/web-xml.html#initParams

Related

Tomcat: How to override web.xml servlet init-param

Imagine a war-file which you can't change. The .war-file's web.xml defines servlets with a set of init-param elements (not: servlet context parameters).
Using Tomcat 7, is there a way to override some of these parameters?
(beside changing the extracted web.xml from the war-file)
It's called init-parameter for a reason. So, you can't.
But you can change values at runtime, that's no problem.
After reading the init parameters put them as attributes of the ServletContext (ctx.setAttribute("name", value))
Create a small (password-protected) page that lists all attributes of the ServletContext and gives the ability to change them.

Accessing a Filter object through a WebApplicationContext

I want to call a method on a Filter object after it has been added according to the web.xml definition. All I got is a WebApplicationContext object (let's call it: wac).
I'm able to add new Filter objects via: wac.getServletContext().addFilter("otherfilter", otherFilter);
Also, I can test successfully for its existence via: wac.getServletContext().getFilterRegistration("myfilter")
But how may I access (and possibly modify) Filter objects which have been added before?
I'm not sure how to do it exactly as you want, but this problem is usually solved using different approach.
You can declare your Filter as a bean in your application context and then register a DelegatingFilterProxy in web.xml to delegate filtering to your filter.
In this case your filter will be a regular Spring bean, and you'll be able to access it like any other bean.
The Servlet API does not provide any mechanism to directly access a Filter instance once it has been added to a ServletContext. The best you are going to get with the Servlet API is the FilterRegistration interface you have already found which lets you modify the same set of configuration options as you can via web.xml.
Depending on exactly what you want to do, you might be able to code your way around this problem using init parameters but that is never going to be a particularly clean solution. I'd go with the DelegatingFilterProxy solution suggested by axtavt.

Can we replace the purpose of init method to the servlet constructor?

Can we replace the pupose of init method to the servlet constructor?
My question is why does servlet need a separate method int(ServletConfig config) for the pupose of initialization we could have achieve the same thing by having a parameterised constructor let XServlet(ServletConfig config) and the container can invoke the same .
Probably because you cannot specify the parameter signature for constructors in an interface.
It is generally considered a bad practice to perform logic in constructor (it should only initialize the field and create object in consistent state). It also makes testing harder.
Also it is much harder to perform injection - when using init the container can create a servlet, inject dependencies and run init. With constructor you would expect to have all the dependencies already set. Wicket works around this problem by injecting Spring beans into page class from superclass constructor - because superclass constructor runs first. However modifying subclass fields from superclass constructor seems wrong.
That being said using separate init method some things simpler and easier to maintain. Also note that EJB promotes #PostConstruct annotation as well.
I guess this choice was made to simplify the coding of servlets. In the current situation, a servlet having no need for specific initialization can be coded like this:
public class MyServlet extends HttpServlet {
// doGet, doPost, etc.
}
If the servlet was initialized using the constructor, it would need to be coded like this:
public class MyServlet extends HttpServlet {
public MyServlet(ServletConfig config) {
super(config);
}
// doGet, doPost, etc.
}
BTW, they even introduced a no-arg init method that can be used to avoid being forced to call super.init(config).
Short answer: NO.
Long answer:
If a servlet contains a constructor and a init method, you will see the constructor is called first, and then the init method (try it out with sysout statements).
A servlet is a java class, so it must follow the java process, so constructor is called first and then the init method (note that the init method is called by your servlet container like tomcat because that's how servlet's are supposed to be initialized; read the servlet specification).
So, if you need to do some operation that is specific to your business need (say create an DB connection or read a set of user details etc); constructors are not the best place to put these things in.
Usually constructors should never have any complex logic/business processing. They should initialize bare minimum member variables and leave the complex things to later; in case of servlets the heavy lifting can be done by init method.
Also note that by the time the init() is called the servlet container is up and ready with it's system resources, i.e it would have initialized the JNDi name bindings, data sources so on and so forth.
So in a way it guarantees you that when you call the init(), it will have the system resources ready for you to work on.
The servlet 3 spec says this:
2.3.1 Loading and Instantiation The servlet container is responsible
for loading and instantiating servlets. The loading and instantiation
can occur when the container is started, or delayed until the
container determines the servlet is needed to service a request. When
the servlet engine is started, needed servlet classes must be located
by the servlet container. The servlet container loads the servlet
class using normal Java class loading facilities. The loading may be
from a local file system, a remote file system, or other network
services. After loading the Servlet class, the container instantiates
it for use.
2.3.2 Initialization After the servlet object is instantiated, the
container must initialize the servlet before it can handle requests
from clients. Initialization is provided so that a servlet can read
persistent configuration data, initialize costly resources (such as
JDBC APIbased connections), and perform other one-time activities. The
container initializes the servlet instance by calling the init method
of the Servlet interface with a unique (per servlet declaration)
object implementing the ServletConfig interface. This configuration
object allows the servlet to access name-value initialization
parameters from the Web application’s configuration information. The
configuration object also gives the servlet access to an object
(implementing the ServletContext interface) that describes the
servlet’s runtime environment. See Chapter 4, Servlet Context for more
information about the ServletContext interface.
Read this part:
The servlet container loads the servlet class using normal Java class loading facilities.
so, the container will have to use standard java class loading mechanism. Which means it can not do what Duncan have just suggested.
int(ServletConfig config) is a life cycle method of Servlet.and it is being called by servlet container.
We can replace the init method code in parameter constructor of super class servlet.
but we can't force the developer to call super class constructor
for example
/*If generic servlet has a constructor like this*/
public GenericServlet(ServletConfig config){
....
}
/*And Developers servlet is calling only default servlet.*/
public MyServlet(){
super();
}
So in this scenario initialization never happens for that servlet. it cause issues problem. because ServletConfig obj is not initialized.
And we cant force the user to call specifict super class constructor.
The simple answer is that you have to have a no-arg ctor and an init method because that is what the spec requires...
Why the spec is written like that is probably a matter of history. These days I think that we might defer construction until the ServletContext is available and call a ctor with that argument. But looking back there was a ServletContext.getServlet(name) method, so that one servlet could look up another on initialisation and communicate with it. For this to work they would all have had to be created up-front and then init'd.
getServlet was deprecated and now returns null (I think it was a security hole for containers that were running multiple apps).

Call servlet on window.open in javascript

How can I call servlet using window.open()?
My code is:
onclick='window.open("/PDFServlet", "popupWindowName",
"dependent=yes, menubar=no, scrollbars=yes, resizable=1, toolbar=no,width800,height=600")'
This should work, if your application is deployed as the ROOT context. If not, you have to specify /context/PDFServlet/

ServletContext.getRequestDispatcher() vs ServletRequest.getRequestDispatcher()

why
getRequestDispatcher(String path) of
the ServletRequest interface cannot
extend outside the current servlet
context
where as
getRequestDispatcher(String path) of
the ServletContext can use the
getContext(String uripath) method to
obtain RequestDispatcher for resources
in foreign contexts.
and how??
Please help
If you use an absolute path such as ("/index.jsp"), there is no difference.
If you use relative path, you must use HttpServletRequest.getRequestDispatcher(). ServletContext.getRequestDispatcher() doesn't allow it.
For example, if you receive your request on http://example.com/myapp/subdir,
RequestDispatcher dispatcher =
request.getRequestDispatcher("index.jsp");
dispatcher.forward( request, response );
Will forward the request to the page http://example.com/myapp/subdir/index.jsp.
In any case, you can't forward request to a resource outside of the context.
The request method getRequestDispatcher() can be used for referring to local servlets within single webapp.
Servlet context based getRequestDispatcher() method can used of referring servlets from other web applications deployed on SAME server.
request.getRequestDispatcher(“url”) means the dispatch is relative to the current HTTP request.Means this is for chaining two servlets with in the same web application
Example
RequestDispatcher reqDispObj = request.getRequestDispatcher("/home.jsp");
getServletContext().getRequestDispatcher(“url”) means the dispatch is relative to the root of the ServletContext.Means this is for chaining two web applications with in the same server/two different servers
Example
RequestDispatcher reqDispObj = getServletContext().getRequestDispatcher("/ContextRoot/home.jsp");
I would think that your first question is simply a matter of scope. The ServletContext is a much more broad scoped object (the whole servlet context) than a ServletRequest, which is simply a single request. You might look to the Servlet specification itself for more detailed information.
As to how, I am sorry but I will have to leave that for others to answer at this time.
Context is stored at the application level scope where as request is stored at page level i.e to say
Web Container brings up the applications one by one and run them inside its JVM. It stores a singleton object in its jvm where it registers anyobject that is put inside it.This singleton is shared across all applications running inside it as it is stored inside the JVM of the container itself.
However for requests, the container creates a request object that is filled with data from request and is passed along from one thread to the other (each thread is a new request that is coming to the server), also request is passed to the threads of same application.
I think you will understand it through these examples below.
Source code structure:
/src/main/webapp/subdir/sample.jsp
/src/main/webapp/sample.jsp
Context is: TestApp So the entry point: http://yourhostname-and-port/TestApp
Forward to RELATIVE path:
Using servletRequest.getRequestDispatcher("sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> \subdir\sample.jsp
http://yourhostname-and-port/TestApp/fwdServlet ==> /sample.jsp
Using servletContext.getRequestDispatcher("sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> java.lang.IllegalArgumentException: Path sample.jsp does not start with a "/" character
http://yourhostname-and-port/TestApp/fwdServlet ==> java.lang.IllegalArgumentException: Path sample.jsp does not start with a "/" character
Forward to ABSOLUTE path:
Using servletRequest.getRequestDispatcher("/sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> /sample.jsp
http://yourhostname-and-port/TestApp/fwdServlet ==> /sample.jsp
Using servletContext.getRequestDispatcher("/sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> /sample.jsp
http://yourhostname-and-port/TestApp/fwdServlet ==> /sample.jsp

Categories

Resources