Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Dart with Spring MVC and Thymeleaf?

I'm currently trying to implement Dart in an existing project which uses Spring MVC (4.0.0) and Thymeleaf (2.1.1) as template engine.

Currently I am deploying all my Dart resources to /dart as shown belown.

<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 rewrites the urls to http://localhost:8080/context/dart/..., which is correct.

Dart works really great if you open a HTML file directly which has the packages folder directly beneath it. However, this is not the case in my project, which has friendly urls like /action/users/browse and you don't have access directly to the HTML file.

When a 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 request handler or a filter that handles all **/packages/** requests (and just use paths relative to the current url)? Or is there an option in Dart where you can set where it should look for packages?

What is the solution (or workaround) for this?

Edit

I currently have a temporary solution that works, but it is dirty and I'm still looking for a cleaner solution.

I added the packages to my classpath and I created a DartPackagesFilter that streams the 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 the packages relatively to the current URL:

<script src="packages/browser/dart.js"></script>

like image 352
Tom Verelst Avatar asked Nov 19 '13 15:11

Tom Verelst


1 Answers

You will need to handle /packages/ requests separately, like your work-around. However, these hacks would only be needed for development when you are working with the actual .dart files.

When you deploy your app, you'll use either dart2js, dart2dart or, most likely, both. These tools produce a monolithic script file which does not rely on the external packages directory.

Since you only need the /packages/ directory for development, it is possible to set the the packages URL through a flag in Dartium. However, in my experience, this is an awkward solution since the flag applies to all Dart applications -- all Dart apps would need to fetch packages through the same URL scheme. It also makes it difficult to share your app with other Dartium installations.

like image 146
James deBoer Avatar answered Sep 19 '22 18:09

James deBoer