I am writing a Servlet that retrieves request parameters but needs to use them in the init method. Since the init method would be called before the doGet method and since the init method does not have a HttpServletRequest object as an argument, I don't know how to get the request parameters.
public class OpenIdServlet extends HttpServlet
{
...
...
private OpenIdManager manager;
#Override
public void init() throws ServletException
{
super.init();
manager = new OpenIdManager();
manager.setRealm("http://localhost:8080/OpenIDSample");
manager.setReturnTo("http://localhost:8080/OpenIDSample/openid"); //I need to append the value of a request parameter here...
}
...
...
}
So the question is: is there any way I can get HttpServletRequest parameters in the init() method of a servlet? If no what other better approach can one use to solve this problem? Thanks.
The init is called once on startup. So you have to live with a partial returnTo, and on request handling (doGet/doPost) complete it with the request parameters.
In fact the manager seems to be request dependent and hence should be created in the request - never as field. As there might be several requests. Maybe persisting as session attribute.
Your question doesn't make sense. There is no request when the init() method is called. It is called during container initialisation.
Do you mean initial parameter? They are available via the ServletContext provided as an argument to init().
Related
I have written a interceptor to make some changes before service call in my spring boot rest service.
Added picture to show my code how I written preHandle method.
In the picture, I want to bring the "orginationTaskServerMockEnabled = true" value which is in
handler -> bean-> mHandler -> dashboardConfig-> originationTaskServerMockEnabled
I tried by it doesnt, is it possible to bring the values from HanlderMethod. If so please help me.
It is not possible to access the handler arguments in the interceptor's preHandle. It is called before the actual invocation of the handler method. The resolution of actual argument types is done during its invocation, so during the execution of preHandle, the argument's value are not resolved yet (but are described by Object handler argument). Only HttpServletRequest and HttpServletResponse are known during the execution so, if the data is attached to the request, you can grab it from there.
Alternatively, you can use an aspect and wrap it around your controller method. From there, you can grab the method arguments then perform your preprocessing.
#Around("execution (* com.pck.controllers.*.*(..)) && #annotation(org.springframework.web.bind.annotation.RequestMapping)")
public Object beforeHandler(ProceedingJoinPoint p){
Object args[] = joinpoint.getArgs();
return joinpoint.proceed();
}
This is one of the interview questions I faced a few days ago:
Is it possible to call the service() method from destroy()?
Thanks in advance.
destroy() is a lifecycle method called by the Servlet container when unloading a specific instance of the Servlet. Similarly, the container will call service() when there's a client requesting the Servlet.
Can we call service() method from destroy() method in Servlet?
Short answer: Yes, as service() is a method like any other.
Long answer: You can, but it doesn't make sense. service() requires a request and a response parameters that are usually provided by the container when the Servlet is called. If you are calling service() by yourself, how are you gonna provide those parameters? What for? Are you gonna use null on both? What good is service() for two empty parameters?
Can we call destroy() method from service() method in Servlet?
Yes, again, you can call destroy() from within the service() as it is also a method like any other. Although still strange, this could make sense sometimes, as destroy() will do whatever logic you have defined (cleanup, remove attributes, etc.).
IMPORTANT: Just bear in mind that simply calling destroy() won't unload the Servlet instance. You do not manage the lifecycle of Servlets in the program, the Servlet Container does.
Purpose of destroy() is to de-allocated/free all the resources used by Servlet instance. By calling destroy() container deregister servlet and its service.
Yes you can call the service(request, response) like anyohter method from destroy() but it wont be executed so its useless to call service method from destroy() as those service method never going to be called/executed, request and response will be null as those objects will not be provided by container.
public void destroy() {
try
{
doPost(null, null); // will not be executed
doGet(null, null); // will not be executed
}
catch(Exception e)
{
e.printStackTrace();
}
}
From Java doc:
public void destroy()
Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. This method is only called once all threads within the servlet's service method have exited or after a timeout period has passed.
After the servlet container calls this method, it will not call the service method again on this servlet.
This method gives the servlet an opportunity to clean up any resources that are being held (for example, memory, file handles, threads) and make sure that any persistent state is synchronized with the servlet's current state in memory.
I'm playing with spring interceptors in last few days and want to catch and handle specific requests through interceptor. What I want to do is to intercept each request before it is processed by specific controller, check whether request contains specific parameters or not. If yes, do some stuff and than sign that stuff to controller which maps that request.
At the end I managed to do that, but when I execute multiple requests at once, with different param values, only param value from last request is assigned to each of controller handler, even every controller should have params which are contained within the request.
Example (executed at the same time):
http://domain.com/controller/method?param=xfg
http://domain.com/controller/method?param=mtc
http://domain.com/controller/method?param=abc
in responses from each request, I get abc! (sometimes I get xfg and abc, or mtc and abc, but never all three of them). When I execute these requests with timeout where every request have time to complete before next one is called, it is working fine.
Does anyone know how to handle this?
Thanks
UPDATED:
public class OLMyInterceptor extends HandlerInterceptorAdapter {
static Logger LOG = Logger.getLogger(OLAuthentificationInterceptor.class);
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Map<String, Object> activeParamsMap = request.getParameterMap();
for(Entry<String, Object> param : activeParamsMap.entrySet()) {
if(param.getKey().startsWith("aP_")) {
activeParams.put(param.getKey().substring(3), param.getValue());
}
}
((MainController) handler).setParams(activeParams);
return true;
}
}
There you have code sample. Every controller of mine extends MainController, that's why I cast handler to MainController, which have setParams method. Every other controller use params in different way.
You must invoke a controller handler method with params, not setter which changes controller state.
The controller must be stateless or thread-safe. When you change state you do not have a guarantee when the setter applies changes - before handlers invoked in another thread, or after. Or another thread invokes setter with other params and previous thread invokes handler method for new params.
I've embedded Jetty, and I'm trying to set an initialization parameter.
The main class Main creates a servlet of Cgi which extends CGI.
Within Main, I have the following code:
ServletContextHandler context2 = new ServletContextHandler(ServletContextHandler.SESSIONS);
context2.setContextPath("/cgi");
context2.setResourceBase("./cgi-bin");
context2.setInitParameter("commandPrefix", "perl");
context2.addServlet(new ServletHolder(new Cgi()), "/");
server.setHandler(context2);
Within Cgi, I check to see the parameter:
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(servletConfig.getInitParameter("commandPrefix"));
super.init(servletConfig);
}
Each time, it prints out null for the getInitParameter call. Then when the Cgi does indeed NEED to use this, it doesn't, because it's not set. Why could this be happening?
You're setting the InitParameter on the ServletContextHandler, but you should be setting it on the ServletHolder.
(It's somewhat confusing, I know)
You've set a context init parameter, not a servlet init parameter. So you need to retrieve it as a context init parameter instead of as a servlet init parameter.
System.out.println(servletConfig.getServletContext().getInitParameter("commandPrefix"));
Alternatively, you can of course also set it as a servlet init parameter instead, but this way the parameter will only be available to the associated servlet only, not to all other servlets running in the same context. This may or may not be what you want, depending on the concrete functional requirement.
Could anyone please tell me why the following line about filter init method invocation is incorrect:
The init method on a filter is called
the first time a servlet mapped to
that filter is invoked.
Because it's called when filter is loaded and initialized by servlet container, which happens during web application startup. Filter's init() method will be called even if it will never intercept a single request.
From the API documentation:
void init(FilterConfig filterConfig) throws ServletException
Called by the web container to indicate to a filter that it is being placed into service. The servlet container calls the init method exactly once after instantiating the filter. The init method must complete successfully before the filter is asked to do any filtering work.