0

I am building a URL Shorter app (like Bitly). It is an SPA using Spring Boot & ReactJS. All web content is served off of index.html. All other routes are presumed to be shortLink redirect requests which should trigger a clickShortUrl() function to fetch the corresponding originalLink and redirect the user to that web address.

Therefore, I want the following routes to redirect to index.html:

@GetMapping(value = {"/", "/home", "/dashboard"})
    public String redirect() {
        return "forward:/index.html";
    }

and all other/unknown routes to trigger a wildcard function:

@RequestMapping(value = "/{shortUrl}", method = RequestMethod.GET)
public Object clickShortUrl(@PathVariable("shortUrl") String shortUrl, @RequestBody ClickDTO request) { 
    // internalLogicHere 
};

Individually, the mappings and functions are working. But combined, the /{shortUrl} wildcard route always takes precedence. I've googled around looking for ways to override this behavior. It seems to be possible a few ways, but all of my attempts have failed.

I read several posts like this suggesting to extend WebMvcConfigurerAdapter and override addViewControllers(ViewControllerRegistry registry) to define view controllers for specific routes. I don't really understand this. Is this the right path? If so, can someone help me understand what ViewControllerRegistry is all about and set me on the right path?

Thank you!

  • (1) Redirecting and forwarding aren't the same thing. (2) Why are you "redirecting" to `index.html` instead of simply rendering it? (3) You _probably_ want to specify `produces = TEXT_HTML_VALUE` on your HTML mapping rather than trying to just separate API and UI by path. – chrylis -cautiouslyoptimistic- Apr 05 '21 at 04:01
  • React builds to `/resources/static`, so my understanding is that Spring Boot will automatically make these files available at their respective paths (e.g., `resources/static/test/me.html` would be available at `:8080/test/me.html`). So all I really need to figure out is how to stop that wildcard route from overriding access to HTML files in `resources/static`. – derpman116 Apr 05 '21 at 13:04
  • Limit the wildcard to `produces = APPLICATION_JSON_VALUE`. – chrylis -cautiouslyoptimistic- Apr 05 '21 at 16:15
  • I tried that. It just throws `org.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supported` – derpman116 Apr 05 '21 at 17:42
  • EDIT: Ignore that ^. I accidentally set to `consumes`, which of course would throw a consumption error in the browser. After changing to `produces` I still hit the wildcard route even when I target the more specific `/home`, `/dashboard`/ or root `/` paths. – derpman116 Apr 05 '21 at 17:49

1 Answers1

0

Answered my own question. Ended up using RegEx in the wildcard route to exclude the static paths used on the front end.

/** Redirect all '/' and '/dashboard/ requests to index.html. */
@GetMapping(value = {"path:/", "path:/dashboard"})
public String redirect() {
    return "forward:/index.html";
}

and the fallback route:

/**
 * Treat all routes as /{shortUrl} clicks except: '/', '/index.html, '/dashboard''
 */
@RequestMapping(value = "{_:^(?!index\\.html|dashboard).*$}")
public Object clickShortUrl(@PathVariable("shortUrl") String shortUrl, @RequestBody ClickDTO request) { 

    // internalLogicHere;
}