Can I pass Httpserveltrequest/response object to run() method using Class variables? - java

I make an ajax call and hit the following code in java class
if("callfirstPageStoredProcedure".equalsIgnoreCase(request.getParameter("mode"))) {
synchronized(this) {
pb = new PayrollBean(request, response, logininfo, request.getParameter("mode"));
pb.startThread();
}
}
so In class payrollBean with the help of this new constructor I set requet and response arguments as Global variables.
Then in run() method I try to access those Parameters but it seems they are not available here and nullPointerexception is thrown.
Constructor :
public PayrollBean(HttpServletRequest request, HttpServletResponse response, LoginInfo loginInfo, String methodToCall){
this.request = request;
this.response = response;
this.loginInfo = loginInfo;
this.methodToCall = methodToCall;
}
Start method Calling :
public void startThread(){
payrollThread=new Thread(this);
payrollThread.start();
System.err.println("The payrollThread is started Now!!!!!!!!!!!!!!!!!!!");
}
Run method:
public void run(){
int InCatch = 0;
try {
if("callfirstPageStoredProcedure".equalsIgnoreCase(methodToCall)) {
callfirstPageStoredProcedure(request, response, loginInfo);
}
}
Any get any idea what am I be doing wrong here?

Each request object is valid only within the scope of a servlet’s
service method, or within the scope of a filter’s doFilter method
Therefore, you shouldn't save any reference to HttpServletRequest and HttpServletResponse for use in another thread. You can not access request parameters once the original request has finished. And your Thread sometimes will be executed before the request has finished and sometimes later.
Instead you should copy the information you need from the original request for later processing.
Extract from Java Servlet Specification:
3.11 Lifetime of the Request Object
Each request object is valid only within the scope of a servlet’s service method, or within the scope of a filter’s doFilter method,
unless the asynchronous processing is enabled for the component and
the startAsync method is invoked on the request object. In the case
where asynchronous processing occurs, the request object remains valid
until complete is invoked on the AsyncContext. Containers commonly
recycle request objects in order to avoid the performance overhead of
request object creation. The developer must be aware that
maintaining references to request objects for which startAsync has not
been called outside the scope described above is not recommended as it
may have indeterminate results.

Related

Servlet thread safety: instance variables vs. request scope attributes [duplicate]

This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Passing an object from JSP page back to Servlet
(3 answers)
How can I store state for an individual browser tab/window?
(2 answers)
Closed 5 years ago.
This is the sample code, illustrating the usage of instance variable and request attribute:
#WebServlet(name = "Upload", urlPatterns = {"/upload"})
#MultipartConfig()
public class Upload extends HttpServlet {
private String txt;
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try{
String txt2 = (String) request.getAttribute("txt2");
//txt and txt2 variables are available for processing.
..........
} finally {
txt = null;//Prepare variable for next request.
}
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
.....
request.setAttribute("txt2", someValue);
//vs
txt = someValue;
processRequest(request, response);
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
.....
processRequest(request, response);
}
}
Now I know that instance variables should be never declared in servlets, because the same servlet is shared between concurent requests. But what about request attributes? Is it safe to use them?
Not sure what you mean by initializing variables. On a servlet you mean or where?
Depending on what you need to do, maybe there are APIs involved in which you don't have control about the contracts (since they are not your APIs).
For example, when requesting is being processed by a filter chain. Maybe one filter is interested on data being set by a filter executed previously in the chain. You don't have means to pass data on the filter chain contract. Request attribute might be an option. Playing with ThreadLocal might be another, but it has performance implications and is not always suitable.
Another example, maybe you forward one request from a servlet to another. Again, you will not have an option to play with whatever member variable you define.
Also, if you were thinking on adding member variables on a servlet, remember Servlets are not thread-safe. What would you do? synchronize request processing, only one request being processed per servlet?
Your servlet is going to serve hundreds on concurrent request each one of them will use same shared instance of the servlet, therefore using private instance variable will lead to inconsistent behavior. Unless you synchronize access to it, which will lead to greater contention on access to this private field, therefore slowing down response time, producing bottleneck.
While storing attribute within binded to single request will allow you to avoid such problem, moreover it was designed to overcome issues similar to yours.

passing data btw classes using request.setParameter, request.getParameter

I have 2 java classes and I want to transfer data between them.
I take user id as parameter in a previous jsp form, and in a java class, using setAttribute I create a atribute named st_id.
then in another java clas I want to retrieve this data, but I get null.pointer exception.
first java file;
public class Signin implements Action {
public String process(HttpServletRequest request, HttpServletResponse response) throws Exception {
Student stu = new StDAO().getUser(request.getParameter("st_id").toString());
request.setAttribute("st_id", request.getParameter("st_id").toString());
...
second;
public class addCourseStu implements Action{
#Override
public String process(HttpServletRequest request, HttpServletResponse response) throws Exception {
TakeCourseDAO pf = new TakeCourseDAO();
String s= (String) request.getAttribute("st_id");
So s is null, it's not my intention.
A request exists from the time the web browser sends it to the web server until the web server (via the servlet) has made its response.Every request for a servlet has its own accessibilty scope. From a servlet, you can:
add new attributes to the request's scope
obtain exisiting attributes from the request's scope
remove exisiting attributes from the request's scope
As you are getting null it is quite obvious that the attribute is not accessed within the scope.
You can try alternatives like Session scope or Application scopes which ever suits you
It is not entirely clear what you want to do but I gather that you want to maintain some state on the server between two requests right?
Look into sessions & cookies for this.
What you do here is weird as it seems you are setting an attribute on an incoming request in the first file.

Purpose of the servlet service method

I thought, that we cannot override service() method in any specific servlet. So what is purpose of httpservlet service method?
From **service method ()** only your actual method (get,post ...etc) decides to call.
The default service() method in an HTTP servlet routes the request to another method based on the HTTP transfer method (POST, and GET). For example, HTTP POST requests are routed to the doPost() method, HTTP GET requests are routed to the doGet() method. This routing enables the servlet to perform different request data processing depending on the transfer method. Because the routing takes place in service(), you do not need to override service() in an HTTP servlet. Instead, override doGet(), anddoPost() depending on the expected request type.
The servlet service() method that perform the task of determining the method that has been called i.e. get/post/trace/head/options/put/delete. These are the 'big seven' methods since they are the most commonly used ones.
After determining the method which is actually called,it then delegates the task to the correspondin method.
You can either use,
public void doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponseresponse)
throws javax.servlet.ServletException,java.io.IOException {...}
or,
public void doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponseresponse)
throws javax.servlet.ServletException,java.io.IOException {...}
instead of,
public void service(javax.servlet.ServletRequest request,
javax.servlet.ServletResponseresponse)
throws javax.servlet.ServletException,java.io.IOException {...}

How to avoid IllegalStateException when referring to request attributes outside of an actual web request

I am working on a solution that should do something if i am in the middle of a web request or something else if not.
What i am doing is
#Autowired private HttpServletRequest request;
And then trying to access a variable:
request.getRequestURI()
But i am getting java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request...
I would like to avoid the exception and somehow ask the HttpServletRequest weather or not i am in a web request or not.
Is there any way to do it?
Example:
Additional info:
#Override
public void trace(String msg) {
if (loggerFactory.isRegisteredUrl(request.getRequestURI())){
loggerFactory.getCustomeLogger(request.getRequestURI()).trace(msg);
return;
}
nativelogger.trace(msg);
}
You should probably (not tested) use RequestContextHolder.getRequestAttributes():
Return the RequestAttributes currently bound to the thread.
Returns:
the RequestAttributes currently bound to the thread, or null if none bound
So, if the method returns null, the current thread is not handling a request. If it returns a non-null value, it is handling one.

how to pass a request of a servlet as a parameter to another helper

I wonder how cn i pass a request parameter of a servlet as a parameter to another java file of my web app that doesm't have POST and GET methods?
Thanks in advance
Antonis
Simply by getting the request parameter from the HttpServletRequest object, and using it as a parameter.
void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException,
java.io.IOException {
String param = req.getParameter("name_of_your_param");
new YourOtherClass().yourOtherMethod(param);
//implement the rest to return a response
}
I'm excluding obvious things like input validation on the parameter (e.g. if the http client didn't send the parameter in the request, the result of getParameter is null) and sending the response.
Please takes some time to become familiar with the Servlet API and refer to it whenever you are curious how to do something with your Servlets and Request/Response objects: http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/index.html
What's the problem with someObject.someMethod(request, response) ?
Your request always passes through a Servlet, so:
extract the needed parameters there
pass them as arguments to the helper
There is another option - to store what you need in a ThreadLocal variable, because each request is handled in a separate thread, but that's to be avoided.

Categories

Resources