springuser2014 / wro4j

Automatically exported from code.google.com/p/wro4j
0 stars 0 forks source link

wro4j does not work behind a RequestDispatcher.include #121

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago

We're working on a far-future expiry solution which includes making a hash of 
servlet resources. These hashes are included in resource URLs and will 
automatically change when resources are updated.

We want this solution to work well with WRO, but we've found that Wro doesn't 
handle being included in a RequestDispatcher.include().

What steps will reproduce the problem?
1. Configure a WroFilter under /wro/* with a group all.js
2. In /index.jsp, get a RequestDispatcher for "/wro/all.js"
3. Perform a include(req, res) on the RequestDispatcher.
4. Observe that Wro fails with an InvalidGroupNameException ("there is no such 
group 'index')

What is the expected output? What do you see instead?
Wro should look for the request attribute 'javax.servlet.include.servlet_path' 
and use that instead of request.getServletURI if the attribute is present.

What version of the product are you using? On what operating system?
1.2.7 on a Mac

Please provide any additional information below.

Original issue reported on code.google.com by eir...@gmail.com on 30 Aug 2010 at 11:12

GoogleCodeExporter commented 9 years ago

Original comment by alex.obj...@gmail.com on 4 Sep 2010 at 11:13

GoogleCodeExporter commented 9 years ago

Original comment by alex.obj...@gmail.com on 4 Sep 2010 at 11:13

GoogleCodeExporter commented 9 years ago
Could you describe why do you think that using a requestDispatcher in index.jsp 
solves your problem?  

I am thinking about a nicer solution for allowing to include hashes in resource 
url's. But until I'll find the solution, I'll try to implement your request.

Original comment by alex.obj...@gmail.com on 4 Sep 2010 at 11:20

GoogleCodeExporter commented 9 years ago
I fixed the issue, it will be available in both releases: 1.2.9 and 1.3.0
I've noticed that when include is used, the response headers are not preserved. 
That is why, I would recommend using forward instead of include. 

Original comment by alex.obj...@gmail.com on 4 Sep 2010 at 2:38

GoogleCodeExporter commented 9 years ago
There is a easy fix for this issue in earlier release. All you have to do is 
the following:

# Create a custom WroManagerFactory:
public class MyWroManagerFactory extends ServletContextAwareWroManagerFactory {
@Override
  protected GroupExtractor newGroupExtractor() {
    return new MyGroupExtractor();
  }
}

# Where MyGroupExtractor is a custom implementation of GroupExtractor which 
checks the "javax.servlet.include.servlet_path" request attribute presence:

public final class MyGroupExtractor implements GroupExtractor {
  /**
   * The name of the attribute where the servlet path is stored when requestDispatcher.include is called.
   */
  public static final String ATTR_INCLUDE_PATH = "javax.servlet.include.servlet_path";

  public String getGroupName(final HttpServletRequest request) {
    if (request == null) {
      throw new IllegalArgumentException("Uri cannot be NULL!");
    }
    final String includeUriPath = (String) request.getAttribute(ATTR_INCLUDE_PATH);
    String uri = request.getRequestURI();
    //check if include or uri path are present and use one of these as request uri.
    uri = includeUriPath != null ? includeUriPath : uri;
    final String groupName = FilenameUtils.getBaseName(uri);
    return StringUtils.isEmpty(groupName) ? null : groupName;
  } 

  //... other methods (@see DefaultGroupExtractor) 
}  

Original comment by alex.obj...@gmail.com on 4 Sep 2010 at 9:19

GoogleCodeExporter commented 9 years ago
And of course the last thing to do, is to configure wro4j filter to use 
MyWroManagerFactory in web.xml:

  <filter>
    <filter-name>WebResourceOptimizer</filter-name>
    <filter-class>
      ro.isdc.wro.http.WroFilter
    </filter-class>
    <init-param>
      <param-name>managerFactoryClassName</param-name>
      <param-value>com.mycompany.MyWroManagerFactory</param-value>
    </init-param>
  </filter>

Original comment by alex.obj...@gmail.com on 4 Sep 2010 at 9:21

GoogleCodeExporter commented 9 years ago

Original comment by alex.obj...@gmail.com on 4 Sep 2010 at 9:21

GoogleCodeExporter commented 9 years ago

Original comment by alex.obj...@gmail.com on 7 Sep 2010 at 11:17

GoogleCodeExporter commented 9 years ago
Alex,

The include() is only used so that we can get a hash of whatever content wro4j 
produces. The actual result is thrown away. We then use the hash to produce a 
URL containing the hash so that whenever the content produced by wro4j changes, 
so does the URL.

Thanks for describing the work around. Looks like it should work, I'll give it 
a spin.

Original comment by eir...@gmail.com on 7 Sep 2010 at 11:54

GoogleCodeExporter commented 9 years ago
The 1.3.0 release will have an interface and few implementations (MD5, SHA-1, 
CRC32) which produce the hash on the resource content. You can checkout the 
1.3.x branch from github (http://github.com/alexo/wro4j/tree/1.3.x) to see if 
it simplify your work. Also this branch contains the fix you need. 

I'll release it very soon, just need a little bit more time for testing & other 
small changes.

Original comment by alex.obj...@gmail.com on 7 Sep 2010 at 12:10