I am currently trying to implement Dart in an existing project that uses Spring MVC (4.0.0) and Thymeleaf (2.1.1) as a template engine.
I am currently deploying all of my Darts resources to /dart , as shown.
<link rel="import" th:href="@{/dart/wb-control-text.html}" /> <script type="application/dart" th:src="@{/dart/packages/polymer/init.dart}"></script> <script th:src="@{/dart/packages/browser/dart.js}"></script>
Thymeleaf is rewriting the urls to http://localhost:8080/context/dart/... , which is correct.
Dart works great if you open the HTML file directly, which has the packages folder right below it. However, this does not apply to my project, which has friendly URLs , for example /action/users/browse , and you do not have direct access to the HTML file.
When the Dart library tries to import a package, I get a 404 error because it is looking for it in the wrong place (e.g. /dart/packages/polymer/packages/polymer/polymer.dart ).
Do I need to provide a URL handler or filter that handles all **/packages/** requests (and just uses paths relative to the current URL)? Or is there an option in Dart where you can set where to look for packages?
What is the solution (or workaround) for this?
Edit
I currently have a workaround, but it's dirty and I'm still looking for a cleaner solution.
I added packages to my classpath and created a DartPackagesFilter that passes resources:
public class DartPackagesFilter extends OncePerRequestFilter @Override protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException { final String uri = request.getRequestURI(); final int index = uri.indexOf("/packages/"); if ( index != -1 ){ final String resourceName = uri.substring(index); writeResourceToResponse(response, resourceName); return; } filterChain.doFilter(request, response); } private void writeResourceToResponse(final HttpServletResponse response, final String resourceName) throws IOException { final ClassPathResource resource = new ClassPathResource(resourceName); response.setContentType(resolveContentType(resourceName)); ChannelUtils.stream(resource.getInputStream(), response.getOutputStream()); } private String resolveContentType(final String resourceName){ if ( resourceName.endsWith("dart") ){ return "application/dart"; } else if ( resourceName.endsWith("js")){ return "text/javascript"; } throw new IllegalArgumentException("Resource must be a Dart or Javascript file!"); } }
In web.xml:
<filter-mapping> <filter-name>DartPackagesFilter</filter-name> <url-pattern>*.dart</url-pattern> <url-pattern>*.js</url-pattern> </filter-mapping>
In my HTML file, I refer to packages relative to the current URL:
<script src="packages/browser/dart.js"></script>