Access HttpServletRequest and HttpServletResponse

2019-07-19 14:53发布

I'm trying to create a Thymeleaf dialect processor which performs a ServletDispatcher.include. I have extended the AbstractElementTagProcessor and overridden the doProcess method. The relevant code fragment is:

@Override
protected void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final IElementTagStructureHandler structureHandler) {
    ServletContext servletContext = null; // TODO: get servlet context
    HttpServletRequest request = null; // TODO: get request
    HttpServletResponse response = null; // TODO: get response

    // Retrieve dispatcher to component JSP view
    RequestDispatcher dispatcher = servletContext.getRequestDispatcher("/something");

    // Create wrapper (acts as response, but stores output in a CharArrayWriter)
    CharResponseWrapper wrapper = new CharResponseWrapper(response);

    // Run the include
    dispatcher.include(request, wrapper);

    String result = wrapper.toString();

    // Create a model with the returned string
    final IModelFactory modelFactory = context.getModelFactory();
    final IModel model = modelFactory.parse(context.getTemplateData(), result);

    // Instruct the engine to replace this entire element with the specified model
    structureHandler.replaceWith(model, false);

I wrote similar code in the past in the form of a custom JSP tag. Problem is: I don't know how to access the ServletContext, HttpServletRequest and the HttpServletResponse! Can this be done at all, or should I just accept that Thymeleaf is too good at hiding the HTTP context?

2条回答
走好不送
2楼-- · 2019-07-19 15:31

I found myself with a very similar requirement of accessing the request from an implementation of IExpressionObjectFactory.

The way i solved it (following @Sebastian Marsching advise in a previous comment) is by accessing the objects registered in IExpressionContext that are available from the view in the context of template evaluation (all those objects described in Appendix A and Appendix B of thymeleaf documentation), so you have access to request, response, servletContext and many other utility objects.

Speaking in code:

IExpressionObjects expressionObjects = context.getExpressionObjects();
HttpServletRequest request = (HttpServletRequest)expressionObjects.getObject("request");

There is also an expressionObjects.getObjectNames() method you can call to get a Set<String> with the names of all registered objects, which in my case gives the following list:

[i18nutils, ctx, root, vars, object, locale, request, response, session,
servletContext, conversions, uris, calendars, dates, bools, numbers, objects,
strings, arrays, lists, sets, maps, aggregates, messages, ids, execInfo,
httpServletRequest, httpSession, fields, themes, mvc, requestdatavalues]
查看更多
冷血范
3楼-- · 2019-07-19 15:36

You can access request (by using #request object that gives you the direct access to javax.servlet.http.HttpServletRequest object) parameters and session (with #session object that gives you direct access to the javax.servlet.http.HttpSession object) attributes directly in Thymeleaf views:

${#request.getAttribute('foo')}
${#request.getParameter('foo')}
${#request.getContextPath()}
${#request.getRequestName()}

<p th:if="${#request.getParameter('yourParameter') != null
      th:text="${#request.getParameter('yourParameter')}"}">Request Param</p>

${#session.getAttribute('foo')}
${#session.id}
${#session.lastAccessedTime}

<p th:if="${session != null}"> th:text="${session.yourAttribute}"</p>

Read more here.

查看更多
登录 后发表回答