0

I've been told that in a Spring MVC web application, when we have a Spring MVC Controller with its local variables, it is possible that multiple requests may use the same Spring MVC Controller instance.

Let's assume I have this Spring MVC Controller.

@Controller
@RequestMapping("/test/me/")
public class TestInstantiation {

    private String myValue;

    @RequestMapping(path = "/try", method = RequestMethod.POST)
    @ResponseBody
    public String execute(String input, HttpServletRequest req, HttpServletResponse httpResp) throws IOException 
    {
        myValue = input;

        //Let's have a lengtly operation here...

        httpResp.getWriter().write(myValue);
    }
}

If multiple clients send a request to /test/me/try with different input values, it is possible that one may receive someone's myValue value.

I am not sure about this claim. I'd appreciate any guidance on that.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
OmerHalit
  • 401
  • 5
  • 18
  • Keeping state in a singleton (which is whatyour servlet is) should not be done. Referencing another stateless singleton is perfectly fine as that isn't state. Also the `extends HttpServlet` doesn't add anyuthing here actually as you are using a spring controller. Nonetheless sharing state in a singleton instance of any class shouldn't be done due to thread safety. – M. Deinum Mar 15 '22 at 11:16
  • @M.Deinum Okay, extending HttpServlet is may bad (copy-paste error here, sorry, I will remove that now). So let's ignore that one. When you say stateless singleton, what do you refer to? Is my servlet a stateless singleton? – OmerHalit Mar 15 '22 at 11:27
  • No it is a stateful one because you are keeping state. The `myValue` is state. If you reference another service (say `AccountService`) which doesn't keep state it isn't a problem as soon as something in that chain keeps state you will run into issues. – M. Deinum Mar 15 '22 at 12:58

2 Answers2

0

You are mixing two different things:

  1. Java's Web Servlet - that is Java EE (today Jakarta EE)'s web-component, that has long been used to develop web applications in Java - namely, a Java object, that can handle (respond to) HTTP messages;

and

  1. Spring Framework's @Controller component - which is, definitely, under the hood used by Java servlet to handle HTTP messages, but that's not something you should worry about. That was the point of bringing @Controllers, to simplify the complexity and boiler-plate of vanilla servlets. You don't create servlet out of controller classes. That means, you don't extend HttpServlet abstract class, with your Spring MVC @Controller class.

What you were told is probably a point about Dispatcher Servlet, which is a Spring Web Framework's implementation for Front-Controller design pattern, that's used in MVC applications.

If multiple clients send a request to /test/me/try with different input values, it is possible that one may receive someone's myValue value.

Every request will be processed in a separate thread - so every client can pass their Request Parameters (query string or payload) and those parameters will be passed into different invocations of your handler method.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
  • Could you take a look at the `ThreadSafety` section of https://stackoverflow.com/a/3106909/1124047 When @BalusC says that it is not ThreadSafe, does that mean the servlet variable may be shared between two distinct request? – OmerHalit Mar 15 '22 at 11:15
-1

If I understand your question correctly, your Controller looks singleton but for member variable myValue you might need to use StringBuffer (if its allowed) to make it thread safe so that multiple requests can use this member variable without any issue.

Or else, if there is no further use of myValue in other methods then I would suggest to make myValue as local to function so that any request will have its own copy of myValue.

Ashish Patil
  • 4,428
  • 1
  • 15
  • 36
  • Would it differ using String or StringBuffer..? Or any primitive type? I am not trying to share `myValue` instance between different servlets. It is the opposite actually. I want to ensure that `myValue` or any other variable within this servlet's scope is unique to the owner of the HTTPRequest this servlet is called for. – OmerHalit Mar 15 '22 at 11:31
  • just edited my answer, please have a look, thanks. – Ashish Patil Mar 15 '22 at 11:51
  • That is exactly what I want to know. So if I keep my variables in the servlet scope, they may be shared among different HttpRequests. Is that right? – OmerHalit Mar 15 '22 at 12:00
  • if you mean to say keeping your variables as member variables of Controller class, then yes, they may be shared among different requests. – Ashish Patil Mar 15 '22 at 12:11
  • `Every request will be processed in a separate thread - so every client can pass their Request Parameters (query string or payload) and those parameters will be passed into different invocations of your handler method.` from @Giorgi Tsiklauri answer. Does this conflict with your statement? Or I am misunderstanding? This is only for the `execute` method in my example and does not include member variables. Right? – OmerHalit Mar 15 '22 at 12:20
  • As Giorgi mentions, you are mixing 2 things, your code has Spring Controller which is by default singleton. Your class member variable `myValue` is keeping state because its getting assigned by incoming requests. If you don't want your incoming request sharing `myValue` then please consider 2 options which I suggested above. thanks. – Ashish Patil Mar 15 '22 at 12:34
  • He is keeping state, shoehorning said state in a `StringBuffer` is still keeping (and sharing) state. – M. Deinum Mar 15 '22 at 12:59