5

I would like to be able to use Spring MVC as REST server and AngularJS on client side.

I have several urls for REST :

  • /rest/products
  • /rest/products/{id}

And i have several urls for the UI :

  • /shop/products
  • /shop/products/{id}

Since it is AngularJS which do the trick on client side, i just want to be able to redirect all default ui urls (not the rest ones) to the index.html file used by AngularJS.

So, in Spring MVC configuration, i would like to be able to do something like that :

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.mypackage.web")
public class WebAppConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/**").setViewName("index");
    }

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/");
        resolver.setSuffix(".html");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

}

With that, i want to delegate all the UI urls handling to AngularJS.

I also want that if the user writes a bad url in the browser he would be redirected by Spring MVC on the index.html file and it will be AngularJS which will do the redirect on the error ui page. I have seen several projects on the web with a single index.html file, but no one handle this error case.

I have been struggling a lot of time trying to do this trick but i can't find a solution.

So my question is : how can i do that ? and more generally, am i wrong with this Spring MVC-AngularJS wanted configuration ?

Very important : I use Spring MVC 3.2 and Tomcat 7.34 without web.xml (full Servlet 3.0)

Thanks a lot.

rico
  • 1,843
  • 2
  • 24
  • 41

4 Answers4

0

Maybe it is possible to solve it via $routeProvider:

$routeProvider.when('/redirect/:redirectParams', {templateUrl: 'partials/homePartial', controller: redirectController});
$routeProvider.when('/home', {templateUrl: 'partials/homePartial', controller: homeController});
$routeProvider.when('/someRoute', {templateUrl: 'partials/somePartial', controller: someController});
$routeProvider.when('/error/', {templateUrl: 'partials/errorPartial', controller: errorController});
$routeProvider.when('/error/:errorMessage', {templateUrl: 'partials/errorPartial', controller: errorController});
$routeProvider.otherwise({redirectTo: '/error'})

Just let the $routeProvider redirect to an error page when the route was not found.

Edit:

I've added a redirectController in the above example. This controller will read the $routeParams, in this case $routeParams.redirectParams and use $location to change the route to /error.

Spring just redirects to http://host:port/index.html/#/redirect/error=blabla. You could and should probably finetune this and support multiple routeParams.

In Spring you would have basically three request mappings:

To redirect all other requests:

@RequestMapping(value = "{path}", method = RequestMethod.GET)
public String redirect(@PathVariable String path) {
   String route = null;
   if (path.equals("/") || path.startsWith("/index.html")) {
     // load index.html
   } else {
     route = "redirect:/index.html/#/redirect/" + path; 
   }
   return route;
}
Eric Platon
  • 9,819
  • 6
  • 41
  • 48
asgoth
  • 35,552
  • 12
  • 89
  • 98
  • This is what i need to do in the angularjs config files. But i need to access the index.html file before. If i put in browser 'localhost:8080/', or that's fine. But if i put 'localhost:8080/blabla' ? I want Spring MVC redirect me on the index.html file and then AngularJS can do what he wants, specially with $routeProvider. – rico Jan 01 '13 at 17:24
  • Why do you need to redirect to index.html? You want to display an error message on the homepage? – asgoth Jan 01 '13 at 17:28
  • I want Spring MVC be able to map all the request urls (except restful ones) to the index.html view. Whatever the request url, i want to display the index.html view. Then, AngularJS, according to the url requested, know which "real" view to display, with the $routeProvider mechanism, as you perfectly showed. In fact, thanks to AngularJS, index.html can handle several views. – rico Jan 01 '13 at 17:36
  • Sorry but you take into account you are already "on" the index.html file. You can access index.html only if you type the url 'http://host:port/' or 'http://host:port/index.html'. But if you type 'http://host:port/shop/products' which is an action unknown by Spring MVC Dispatcher servlet, you will get a 404 error before accessing the index.html file. My problem is a Spring MVC config one : i want, whatever the url typed, to access index.html. That's why i tried registry.addViewController("/**").setViewName("index") but it does not work. Thanks. – rico Jan 01 '13 at 18:06
  • So? You let Spring [redirect](http://stackoverflow.com/a/4584460/1916258) from 'host:port/shop/products' to 'host:port/index.html'. – asgoth Jan 01 '13 at 18:14
  • OK. Can you provide the full Spring MVC configuration to do that for 'host:port/shop/products' but also for all other urls please ? Thanks. – rico Jan 01 '13 at 18:44
  • I am able to do that for specific urls with : registry.addViewController("/shop/products").setViewName("index"); registry.addViewController("/shop/products/*").setViewName("index"); But it does not work with : registry.addViewController("/**").setViewName("index"); – rico Jan 01 '13 at 18:51
  • You have to use request mappings. Check the link in my answer. – asgoth Jan 01 '13 at 19:13
0

I think you can write an Interceptor which allows some known URLs like /rest/, /resources/, /webjars/* and for any other URLs redirect to index.html.

K. Siva Prasad Reddy
  • 11,786
  • 12
  • 68
  • 95
0

Try using urlrewritefilter

This should do the work for you. You'll have to configure/add it in your web.xml to every url would be handled and you can manipulate it to redirect to the index.html

Dobidoo
  • 564
  • 6
  • 21
0

I know its a bit late but in case someone run into the same trouble here's the URL filter sample put in your classpath urlwrite.xml

You can set redirection of certain urls you want to filter.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
        "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">

<!-- Configuration file for UrlRewriteFilter http://www.tuckey.org/urlrewrite/ -->

<urlrewrite>

    <rule>
        <note>
            The rule means that requests to /test/status/ will be redirected
            to
            /rewrite-status
            the url will be rewritten.
        </note>
        <from>/index.ipxs/directory</from>
        <to type="redirect">/index.ipxs/marketplace</to>

    </rule>
    <rule>
        <from>/index.ipxs/faq</from>
        <to type="redirect">/index.ipxs/marketplace</to>
    </rule>
    <rule>
        <from>/index.ipxs/marketplace</from>
        <to type="redirect">/iPlexus/index.ipxs</to>
    </rule>

</urlrewrite>
Dobidoo
  • 564
  • 6
  • 21