如何在servlet环境中初始化API [英] How to initialize an API in servlet environment

查看:115
本文介绍了如何在servlet环境中初始化API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

显然我想写出去耦组件。一部分是一个表单引擎。我不希望它依赖于servlet API,但是我必须根据请求(或至少每个会话)进行初始化。

Obviously I want to write decoupled components. One part is a form engine. I don't want it to be dependent on the servlet API, but I have to inialize it per-request (or at least per-session).

在应用程序中我会使用类似

In an application I would use something like

public static void setLocale(Locale l);

那么我的个别类可以用静态getter获取它。这在servlet环境中是不可行的(servlets甚至缺少一个 static getServletContext()方法,通过静态行为可以模拟)。

then my individual classes could get it with a static getter. This is not feasable in a servlet environment (servlets lack even a static getServletContext() method thru which static behaviour could be emulated).

我绝对不想使用工厂(我将有10+类,所有这些都将使用一些配置,至少Locale)或更差:构造每个对象与参数块(其中包含code> Locale 和其他设置)。

I absolutely don't want to use factory (I will have 10+ classes all of which will use some configuration, Locale at least) or worse than that: construct each object with a parameter block (which contains Locale and other settings).

我想知道在这种情况下最好的做法是什么。静态行为是否以可用的方式模拟,或者servlet API是否有这个问题的答案?

I would like to know what's the best practive in this situation. Can static behavior emulated in a usable way or does the servlet API has an answer to this problem?

如果其他任何可能性都失败,我会考虑使用类似的东西:

If every other possibility fails I thought of using something like:

class MyParameters {
    private Map<Thread, MyParameters> threadParameters = new Map<Thread, MyParameters>();

    public static void setParameters(MyParameters parameters) {
        threadParameters.put(Thread.getCurrentThread(), parameters);
    }

    public static MyParameters getParameters() {
        return threadParameters.get(Thread.getCurrentThread());
    }    
}

...但这会产生一些安全问题servlet可能无法初始化它,并使用在同一线程提供的先前请求期间设置的值)。 - 虽然使用不同的用户的区域设置不是很大的威胁。

... but this creates some security concerns (a servlet may fail to initialize it and use the values set up during a previous request served by the same thread). - Although using a different user's Locale is not as much of a threat.

推荐答案


但是我必须根据请求(或至少每个会话)进行初始化。

使用 过滤器 HttpServlet ServletRequestListener (或 HttpSessionListener )。

Use a Filter, HttpServlet or ServletRequestListener (or a HttpSessionListener).


但这会创造一些安全性关心

此外,线程由容器合并。对于不同的后续请求,相同的线程可以多次重复使用。当你把一些东西放在线程中,不要在请求结束时删除它,你最终会得到threadunsafe代码。

Also, threads are pooled by the container. The very same thread can be reused more than once for different subsequent requests. When you put something in the thread and don't remove it by the end of the request, you would end up with threadunsafe code.

你最好的打算是创建一个 ThreadLocal< T> 类。假设你想要它是基​​于请求/响应的,这里是一个开始示例:

Your best bet is to create a ThreadLocal<T> class. Assuming that you want it to be request/response based, here's a kickoff example:

public final class Context {

    private static ThreadLocal<Context> instance = new ThreadLocal<Context>();

    private HttpServletRequest request;
    private HttpServletResponse response;

    private Context(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }

    public static Context getInstance() {
        return instance.get();
    }

    public static Context newInstance(HttpServletRequest request, HttpServletResponse response) {
        Context context = new Context(request, response);
        instance.set(context);
        return context;
    }

    public void release() {
        instance.remove();
    }

    // ...
}

获取并设置它在一个过滤器

Context context = null;
try {
    context = Context.newInstance(request, response);
    chain.doFilter(request, response);
} finally {
    if (context != null) context.release();
}

(请注意,非常重要在 try 块的 finally 块中释放上下文,否则不会每当请求 - 响应处理引发异常时,都将被释放)

(note that it's very important to release the context in the finally block of the try block where you're acquiring it, otherwise it won't be released whenever the request-response processing throws an exception)

最后,您可以在代码中随处可见,如下所示:

Finally you can get it everywhere in your code as follows:

Context context = Context.getInstance();
context.setLocale(locale); 
Locale foo = context.getLocale();
// ...

其中您将方法委托给本地请求和/或响应变量。

wherein you delegate the methods to the local request and/or response variables.

请注意,类似的结构已经存在在一些MVC框架中,如JSF及其 FacesContext的 。而不是拥有一个人,你想看看那边的草是否更环保。

Note that similar construct already exist in some MVC frameworks, like JSF with its FacesContext. Instead of homegrowing one, you'd like to look if the grass isn't greener over there.

这篇关于如何在servlet环境中初始化API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆