Класс одиночного действия для нескольких динамических URI выдает исключение при одновременном запросе - PullRequest
0 голосов
/ 29 октября 2010

Я разработал веб-сайт, используя Struts2 в качестве контроллера, и интегрировал его с Spring и Hibernate для выполнения бизнес-логики и работы с БД. URI веб-сайта: http://my.domian.com/URI;, который {URI} динамически генерируется администратором. Сопоставление каждого 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, что используется в бизнес-логике или запросах в БД.

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

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

1 Ответ

0 голосов
/ 01 ноября 2010

Вот упрощенная версия 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/Ahttp: // www.domain.com/Bhttp: // www.domain.com/Chttp: // www.domain.com/Dhttp: // www.domain.com/Eодновременно все страницы будут отображаться в браузере, но содержимое A отображается в A и B, C является правильным, и существует очень высокая вероятность того, что содержимое D и E также является неправильным.

...