Load a properties file in a servlet - java

I have a properties file in the WEB-INF with some properties that need to be used by my servlet (properties like a database password,...). What's the best way to load this file? Should I Override the init method of the servlet so that I only load the file once?
Thanks

I am not saying that this way is correct or anything since I don't work with JEE but from what I remember you can use ServletContextListener methods for this. Just implement it like
class ContextListenerImpl implements ServletContextListener {
#Override
public void contextDestroyed(ServletContextEvent sce) {
//lets skip it for now
}
#Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext sc = sce.getServletContext();
//read parameter from properties and add it to servlet context attributes
sc.setAttribute("yourParameterName", "value");
}
}
You should be able to use it in any servlet via for instance
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//...
getServletContext().getAttribute("yourParameterName");
//...
}
BTW value of attributes can hold also other objects, not only Strings.
Oh, and lets not forget to add this listener to your web application. Just add
<listener>
<listener-class>full.name.of.ContextListenerImpl</listener-class>
</listener>
to your web.xml file.

Related

Cannot run simple servlet with use of annotations

I am new java programmer. So I do understand the process of running servlet through mapping etc in the web.xml and I also can launch the servlet through annotation, my question is when I use the annotation, and run the project on the server, why do I have to write the serlvet name in the URL after project name for it to launch.
Is there any way without using web.xml file at all, giving an annotation and then when I run project on server that it would automatically launch and run the servlet? Instead of my writing the servlet name and hitting enter for it to launch.
#WebServlet(urlPatterns = {"/GetDate"})
public class GetDate extends HttpServlet{
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Date date =new Date();
resp.setContentType("text/html");//this says we will send back html type
//get a pen to write back
PrintWriter pen=resp.getWriter();
//write back
pen.write(date.toString());
}
}
I would like the above simple servlet to just launch automatically as soon as I select run on server from eclipse.
You can specify load on startup in annotation, then the servlet's init() method is invoked when the web server starts
#WebServlet(urlPatterns = {"/GetDate"}, loadOnStartup=1)
public class GetDate extends HttpServlet{
#Override
public void init() throws ServletException {
// do some init stuff
}
It's all in the #WebServlet notation. If you change your code to be:
#WebServlet(urlPatterns = {"/"})
public class GetDate extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Date date =new Date();
resp.setContentType("text/html");//this says we will send back html type
//get a pen to write back
PrintWriter pen=resp.getWriter();
//write back
pen.write(date.toString());
}
}
Then the servlet is served at the / URL (after your webapplication name)
Be careful doing this. Traditionally you serve HTML resources from the / location. If you take this over with your servlet then you can't serve HTML. Additionally if you have more than one servlet then which one gets the / path - where do the rest go? It can be a bit self documenting to have the URL match the servlet. Note that there is no need to keep it the same name as the servlet - call it /myBigLongURLMapping if you like - the name is up to you.
Instead of #WebServlet(urlPatterns = {"/GetDate"}) write like this #WebServlet("/GetDate")
#WebServlet("/GetDate")
public class GetDate extends HttpServlet{
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Date date =new Date();
resp.setContentType("text/html");//this says we will send back html type
//get a pen to write back
PrintWriter pen=resp.getWriter();
//write back
pen.write(date.toString());
}
}

Whats the difference between ActionContext,ServletContext and ServletActionContext?

In Java EE, we often use ActionContext,ServletContext and ServletActionContext, they have similar name, but I don't know the difference between them.
I only know the ServletActionContext inherit the ActionContext.
Someone can explain them?
There have many difference between them.
ServletContext
From the ServletContext's package(javax.servlet.ServletContext) we can know it is standard JavaEE WebApplication class library.
ServletContext provides the standard Servlet run-time environment. Actually is some methods of servlet communicate with web container.
public interface ServletContext {
// Returns the URL prefix for the ServletContext.
public String getServletContextName();
//Returns the context-path for the web-application.
public String getContextPath();
//Returns the ServletContext for the uri.
public ServletContext getContext(String uri);
//Returns the real file path for the given uri.
public String getRealPath(String uri);
public RequestDispatcher getNamedDispatcher(String servletName);
public RequestDispatcher getRequestDispatcher(String uri);
ServletContext is included in the ServletConfig, and ServletConfig often read from servlet or filter's init() method:
servletConfig.getServletContext()
filterConfig.getServletContext()
ActionContext
Comes from Struts, but at first comes from Struts1 and Struts2 they are different.
From Struts1:
A servlet (servlet org.apache.struts.action.ActionServlet) handle all the *.do action.
From Struts2:
The filter(org.apache.struts2.dispatcher.FilterDispatcher) handle all the request.
Because struts1 belongs to servlet scope. struts1 action's essentially is servlet.
struts2 action is normal Java bean, out of the servlet limitations.
The ActionContext makes up the lost WEB environment after the strtus2 action out of the stand servlet framework.
The ActionContext main function:
Provide the WEB context.
Solve the thread security issue.
Solve the incompatibility problem with other Framework(such as: webLogic))
ServletActionContext
As you say, ServletActionContext is ActionContext's subclass.
Its functions is starting at ActionContext, and encapsulate the methods, make it more simple and intuitive.
We can also study its source code:
public class ServletActionContext extends ActionContext implements StrutsStatics {
//HTTP servlet request
public static void setRequest(HttpServletRequest request) {
ActionContext.getContext().put(HTTP_REQUEST, request);
}
public static HttpServletRequest getRequest() {
return (HttpServletRequest) ActionContext.getContext().get(HTTP_REQUEST);
}
//HTTP servlet response
public static void setResponse(HttpServletResponse response) {
ActionContext.getContext().put(HTTP_RESPONSE, response);
}
public static HttpServletResponse getResponse() {
return (HttpServletResponse) ActionContext.getContext().get(HTTP_RESPONSE);
}
//servlet context.
public static ServletContext getServletContext() {
return (ServletContext) ActionContext.getContext().get(SERVLET_CONTEXT);
}
public static void setServletContext(ServletContext servletContext) {
ActionContext.getContext().put(SERVLET_CONTEXT, servletContext);
}
From above we can know the ServletActionContext extends ActionContext.

Different ways to get Servlet Context

Could anybody explain me what is the difference between this ways of getting the ServletContext of an HttpServlet?
doGet( HttpServletRequest request, ... ){
getServletConfig( ).getServletContext( );
request.getSession( ).getServletContext( );
getServletContext( );
}
Is there any difference in performance or in the context itself? If so, which is the best way? Are there any other way of retrieving the context?
There's one more.
request.getServletContext();
There's technically no difference in performance, only the request.getSession() will implicitly create the HTTP session object if not created yet. So if this is not done yet, then grabbing the servlet context via the session may take a few nanoseconds longer if the session isn't created yet.
There's also no difference in the returned context. Those methods are all just for convenience and which method to obtain the context depends on the context ;) you're currently sitting in.
If you're sitting in a method invoked by servlet's service() (such as doGet(), doPost(), etc), then just use the inherited getServletContext() method. Other ways only unnecessarily add more characters to the source code.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
ServletContext context = getServletContext();
// ...
}
If you're sitting in servlet's init(ServletConfig) method, then the inherited getServletContext() isn't available yet as long as you haven't called super.init(config). You'd need to grab it from ServletConfig.
#Override
public void init(ServletConfig config) {
ServletContext context = config.getServletContext();
// ...
}
But much better is to override init() instead. In a decent servlet you usually never need to override init(ServletConfig).
#Override
public void init() {
ServletContext context = getServletContext();
// ...
}
If you're not sitting in a servlet but in e.g. a filter which lacks the inherited getServletContext() method and you only have ServletRequest at hands, then you could grab it from there.
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
ServletContext context = request.getServletContext();
// ...
}
Note that this is new since Servlet 3.0. Previously, you'd have to grab it from the session.
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
ServletContext context = request.getSession().getServletContext();
// ...
}
This is however not nice if you worry about unnecessary session creation. Hence the introduction of ServletRequest#getServletContext() — although you could also simply extract it from FilterConfig (hey, there's yet another way!).
private FilterConfig config;
#Override
public void init(FilterConfig config) {
this.config = config;
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
ServletContext context = config.getServletContext();
// ...
}
And then there are HTTP session listeners where you could listen on a.o. session destroy. There's no other way to obtain the servlet context than via HttpSession#getServletContext().
#Override
public void sessionDestroyed(HttpSessionEvent event) {
ServletContext context = event.getSession().getServletContext();
// ...
}
Here you don't need to worry about unnecessary session creation because it's at that point already created for long beforehand. Do note that there's no ServletRequest anywhere as there's not necessarily means of an active HTTP request during server side session timeout.
As last, there's also ServletContext#getContext() which returns the ServletContext of a different web application deployed to same server (this works only if the server is configured to enable cross context access on the target webapp).
ServletContext otherContext = context.getContext("/otherContextPath");
But this already requires the current ServletContext to start with, for which you should by now already know which way to use to obtain it.

Porting a servlet to a web service - accessing the context?

Consider a simply servlet:
// MyServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response)
{
UtilClass.doSomething(getServletContext().getRealPath(SOME_FILE));
}
And the utility class does something with the file:
// UtilClass.java
public String doSomething(String filePath)
{
File f = new File(filePath);
String s = readWhateverFrom(f);
return s;
}
I am now porting the doSomething() function to a web service running under Tomcat and Axis2. How would I port it so that I can still access the context and get access to a file under the servlet?
You should get ahold of your (jax-ws) MessageContext. This would depend on your configuration, but perhaps using
#Resource
private WebServiceContext wsCtx;
and in your method:
MessageContext messageContext = wsCtx.getMessageContext()
ServletContext ctx = (ServletContext)
messageContext.getProperty(MessageContext.SERVLET_CONTEXT);
Edit: Seems like Axis2 (as well as Axis) support the following:
HttpServlet servlet = (HttpServlet)
MessageContext.getCurrentContext().getProperty(HTTPConstants.MC_HTTP_SERVLET);
ServletContext ctx = servlet.getServletContext();
With the following imports:
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.http.HTTPConstants;
Sounds like a job for a Servlet Filter and a ThreadLocal. Axis is running within a Servlet Context, too. So all you have to do is to implement a custom javax.servlet.Filter, stuffing in the ServletRequest into a ThreadLocal where you can access it from within your utility class. You can get the ServletContext from the FilterConfig.

How to use the "application" object in a Servlet?

If we are coding a JSP file, we just need to use the embedded "application" object. But how to use it in a Servlet?
The application object in JSP is called the ServletContext object in a servlet. This is available by the inherited GenericServlet#getServletContext() method. You can call this anywhere in your servlet except of the init(ServletConfig) method.
public class YourServlet extends HttpServlet {
#Override
public void init() throws ServletException {
ServletContext ctx = getServletContext();
// ...
}
#Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
ServletContext ctx = getServletContext();
// ...
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
ServletContext ctx = getServletContext();
// ...
}
}
See also Different ways to get Servlet Context.
The application object references javax.servlet.ServletContext and you should be able to reference that in your servlets.
To reference the ServletContext you will need to do the following:
// Get the ServletContext
ServletConfig config = getServletConfig();
ServletContext sc = config.getServletContext();
From then on you would use the sc object in the same way you would use the application object in your JSPs.
Try this:
ServletContext application = getServletConfig().getServletContext();
In a Java web application you often have the request object. So you can get the "application" object like this:
request.getServletContext().getServerInfo()

Categories