Один класс действий для нескольких динамических URI выдает исключение при одновременном запросе

Я разработал веб-сайт, используя Struts2 в качестве контроллера, и интегрировал его с Spring и Hibernate для выполнения бизнес-логики и работы с БД. URI веб-сайта: http://my.domian.com/URI; который {URI} создается динамически с помощью административной cms. Сопоставление каждого uri с сервлетом выполняется с помощью Apache mod_rewrite следующим образом:

RewriteCond %{HTTP_HOST} ^www\.domain\.com
RewriteRule ^([a-zA-Z0-9_-]+)$ /dynamic\.action?f=$1 [QSA,L]  

(Перед любой дополнительной информацией, является ли это хорошим и подходящим подходом?)

Конфигурация распорок является типично академической, так как:

<package name="Default" extends="struts-default" namespace="/">  
    ...  
    <action name="dynamic" class="DynamicContentAction">  
        <result name="index">/content/web/dynamic/index.jsp</result>  
    </action>  
</package>

DynamicContentAction расширяет ActionSupport и реализует ServletRequestAware, ServletContextAware. Я проверяю пару вещей (например, текущий язык посещения, который идентифицируется как поддомен), ищу в базе данных, является ли запрошенный uri допустимым или нет, генерирую содержимое этого uri и устанавливаю пару глобальных переменных времени выполнения ( например, текущий идентификатор страницы посещения, конфигурация макета из-за текущего языка посещения ...) и поместите его в объект запроса в этом сервлете.

Все выглядит хорошо и даже работает отлично, если только один пользователь не запрашивает слишком много динамических страниц одновременно. «Слишком много» в моем случае — это минимум 9-10 страниц. В этом случае он выбрасывает исключения, разные! Иногда запрос HttpServletRequest имеет значение null, иногда ServletContext servletContext имеет значение null, иногда это нормально, но переменные времени выполнения имеют значение null, которое используется в бизнес-логике или запросах к базе данных.

Я погуглил об этом и узнал, что это действие создается «на запрос». Разве это не так? Если есть действие для каждого запроса, что не так с этим конфликтом или «обнуляемостью». Должен ли я делать что-то похожее на нить в этом действии, кроме резьбы распорок?

Я был бы очень признателен, если бы вы могли мне помочь или указать мне направление.


person Khosrow    schedule 29.10.2010    source источник


Ответы (1)


Вот упрощенная версия DynamicContentAction.java.

public class DynamicContentAction extends ActionSupport implements ServletRequestAware, ServletContextAware {
    private HttpServletRequest request;
    private ServletContext servletContext;

    private ResourceSelectorService resourceSelectorService;

    private String f = null;

    public String execute() {
        if ( f != null ) {
            HashMap<String, Object> resolvedURI = resourceSelectorService.resolveURI(f);

            if ( resolvedURI.get("ERROR").equals(true) ) {
                //Generating nice 404 error page content
            } else {
                //Generating Content
                //and put it on request object as:
                //request.setAttribute("attrName", resourceContent);
            }
        }

        else {
            //Generating nice 404 error page content
        }

        request = null;
        servletContext = null;

        f = null;

        return "index";
    }

    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;  
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;  
    }

    public void setF(String f) {
        this.f = f;
    }

    public String getF() {
        return f;
    }
}

Пока я пишу этот пост, я понял, что этот класс НЕ является потокобезопасным. Это? Поэтому я немного изменил его следующим образом:

Вот более новая версия DynamicContentAction.java

public class DynamicContentAction extends ActionSupport {
    private ResourceSelectorService resourceSelectorService;

    private String f = null;

    public String execute() {
        if ( f != null ) {
            final HttpServletRequest request = ServletActionContext.getRequest();
            final ServletContext servletContext = ServletActionContext.getServletContext();

            HashMap<String, Object> resolvedURI = resourceSelectorService.resolveURI(f);

            if ( resolvedURI.get("ERROR").equals(true) ) {
                //Generating nice 404 error page content
            } else {
                //Generating Content
                //and put it on request object as:
                //request.setAttribute("attrName", resourceContent);
            }
            f = null;
        }

        else {
            //Generating nice 404 error page content
        }

        return "index";
    }

    public void setF(String f) {
        this.f = f;
    }

    public String getF() {
        return f;
    }
}

и проблема с нулевыми вещами почти ушла, но конфликт с генерируемым контентом все еще есть. Например, если пользователь пытается открыть:

http:// www.domain.com/A
http:// www.domain.com/B
http:// www.domain.com/C
http:// www.domain.com/D
http:// www.domain.com/E

одновременно все страницы будут отображаться в браузере, но содержимое A отображается в A и B, C правильно, и есть очень большая вероятность, что содержимое D и E также неверно.

person Khosrow    schedule 01.11.2010