Une fois que je suis tombé sur un motif, où Quel est le point d'avoir ces servletrequest code> et les objets de réponse sont mis sur les variables code> ThreadLocal code>. La classe Servlet a également des méthodes pour obtenir des objets de demande et de réponse actuels. Donc, afin d'obtenir ces objets, vous devez toujours utiliser avec un objet de servlet. p>
theallocal code> variables locales? p>
8 Réponses :
Ils vous permettent d'accéder au HTTPServletReQuest et de HTTPServletResponse d'autres classes de votre projet sans avoir à passer des références à ces objets aux autres classes. Ce n'est pas un modèle que j'aime particulièrement car il a tendance à mélanger votre code de niveau Web avec votre logique commerciale et rend le test de l'unité plus difficile. P>
Le point est d'avoir les objets de demande et de réponse dans des classes qui ne les auraient autrement pas (par exemple, ils ne sont pas des servlets). Les haricots gérés JSF sont un exemple - leurs méthodes ne prennent pas La raison pour laquelle cela fonctionne est que chaque demande est traitée par un thread séparé (par le conteneur de servlet). Alors thread = demande. Mais il y a une mise en garde - les conteneurs ont tendance à utiliser des piscines de fil. Il faut donc toujours définir une nouvelle demande dans le fillocal et la nettoyer de préférence ensuite (par exemple dans un filtre Mais vous devriez vraiment éviter cela dans votre code. Si vous avez besoin de quelque chose de la demande ou de la réponse, passez-le en tant que procédé. Sinon, vous risquez de violer les limites de la couche (si vous êtes tenté d'utiliser la demande dans la couche de service, par exemple) P> httpservletQuest code>. Vous pouvez donc obtenir la demande via le
facescontext code>, qui les a dans
ThreadLocal code> variables. P>
code>). Sinon, vous pouvez obtenir un comportement inattendu. P>
J'ai fait face à ce genre de choses dans GWT RemoteService, et je me suis demandé pourquoi ils l'ont fait. Après avoir creusé davantage dans le code, j'ai réalisé qu'ils fournissent une interface supplémentaire à mettre en œuvre par votre propre RPCService qui devrait également étendre RemoteServiceServlet. Votre propre service dans ce cas peut ignorer le servlet derrière celui-ci
Je ne suis pas sûr à 100% de l'intention de l'auteur du code que vous auriez rencontré, mais je suppose que l'idée existe que SerbletQuest code> est disponible à partir de n'importe quelle méthode le code sans le transmettre en tant que paramètre ou paramètre comme variable d'instance. Habituellement
ThreadLocal Code> La variable est statique et il existe une méthode exposée qui permet d'obtenir l'instance de
servletrequest code> de manière statique. Par exemple, vous pouvez accéder à
servleRequest code> dans Struts Frosses en utilisant facilement cette technique. P>
Lorsque vous avez un objet qui n'est pas thread-coffre-fort, mais que vous souhaitez éviter de synchroniser l'accès à cet objet (SimpleDateDateFormat). Au lieu de cela, donnez à chaque fil de son propre instance de l'objet. P>
Vous devez faire très attention à la nettoyage de tout threadlocals que vous GET () CODE> ou
SET () CODE> En utilisant le
Supprimer () CODE> Méthode. P>
Étant donné que la requête et les objets de réponse sont stockés dans des variables locales de fil, vous obtenez un accès de fil à thread à ces objets sans avoir à les transmettre en tant que paramètres de méthode.
Exemple 1: sans fil local p>
public class MyServlet extends Servlet { private MyObject myObject = new MyObject(); private static ThreadLocal<ServletRequest> currentRequest = new ThreadLocal<ServletRequest>(); public static ServletRequest getCurrentRequest() { return currentRequest.get(); } private static ThreadLocal<ServletResponse> currentResponse = new ThreadLocal<ServletResponse>(); public static ServletResponse getCurrentResponse() { return currentResponse.get(); } public void service(ServletRequest request, ServletResponse response) { ... currentRequest.set(request); currentResponse.set(response); ... myObject.doSomething(); } } public class MyObject { private MyOtherObject myOtherObject = new MyOtherObject(); public void doSomething() { // I do not need to know about request / response as I do nothing with them myOtherObject.doSomethingElse(); } } public class MyOtherObject { public void doSomethingElse() { // Now I can get the current request / response in a thread safe // manner and without having to accept them as parameters ServletRequest request = MyServlet.getCurrentRequest(); ServletResponse response = MyServlet.getCurrentResponse(); // Do something with request / response } }
@matt B - Je n'ai pas eu ton point. La demande et la réponse sont stockées dans des lignes fillocales, aucun autre thread ne peut interférer avec ce
D'autres ont très bien indiqué quelle est l'utilisation des locaux de fil dans le scénario que vous avez présenté. Mais soyez prévenu cependant, le fil des implémentations de comptoir local est un «thread» spécifique et rompez lorsque les choses s'éloignent d'un seul fil par demande. Exemple serait des serveurs d'événements basés sur des événements dans lesquels une poignée de threads est utilisée pour de nombreuses demandes d'utilisateurs simultanément. P>
C'est vraiment terrible. Vous devez obtenir les valeurs dont vous avez besoin de la requête / session HTTP dès que vous le pouvez. Vous pouvez transmettre ces valeurs dans les invocations de méthode ou transférer des objets. Vous devriez s'efforcer d'écrire des méthodes / classes sans la technologie. Si votre méthode / classe obtient une demande HTTP de ThreadLocal, il s'agit d'une classe sans valeur - elle n'est plus utile dans aucun contexte non http. p>
Il est particulièrement choquant pour que les gens tirent des demandes HTTP de ThreadLocal dans BOS (Business Objects) ou DAOS. Les demandes HTTP ne doivent jamais apparaître dans aucun calque autre que la couche de présentation de l'application. P>
Je pense que le meilleur cas peut être comme .. p>
Objet de connexion Une fois créé dans la couche de service placée dans ThreadLocal puis appelez une couche DAO, obtenez l'objet de connexion à partir de THFLOCAL. P>