Emperor
Emperor

Reputation: 355

How to redirect from Spring controller to React page

I have two modules. One that contains my front-end, which is my React app. And one which contains my back-end, my Spring stuff. I want to visit a controller in my Spring app that will redirect me to my React app.

Upvotes: 0

Views: 10527

Answers (3)

Uros Velickovic
Uros Velickovic

Reputation: 25

How to get index.html from a react bundle location:

You can set resource.location in application.properties to whatever you want. For testing puproses I set it to a build folder of my react project. Then i only npm run build and new changes are visible.

@Configuration
@EnableWebMvc
@Slf4j
public class WebConfig implements WebMvcConfigurer {

    @Value("${resource.location:}")
    String resourceLocation;
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (!resourceLocation.isEmpty()) {
            log.info("static data path 'file:" + resourceLocation + "/static/'");
            registry.addResourceHandler("/static/**")
                    .addResourceLocations("file:" + resourceLocation + "/static/");
            registry.addResourceHandler("/*.js")
                    .addResourceLocations("file:" + resourceLocation + "/");
            registry.addResourceHandler("/*.json")
                    .addResourceLocations("file:" + resourceLocation + "/");
            registry.addResourceHandler("/*.ico")
                    .addResourceLocations("file:" + resourceLocation);
            registry.addResourceHandler("/index.html", "/")
                    .addResourceLocations("file:" + resourceLocation + "/index.html");
        }
    }

How to redirect from spring to react path:

I have created errorHandler so that i catch all paths that are not handled, and then i return index.html with parameter path.

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
@Slf4j
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    log.info("no handler found for " + ex.getRequestURL());
    headers.add("location", "index.html?path="+ex.getRequestURL());
    return new ResponseEntity<>(null, headers, HttpStatus.SEE_OTHER);
}

}

On react side on index.html page i get path and send it as prop to NavigationBar

let path = window.location.search
console.log(path)
let pathMatch = path.match("(path=)(\\S*?)(&|$)")
if (pathMatch) {
  path = pathMatch[2]
}
ReactDOM.render(
  < React.StrictMode >
    <BrowserRouter>
      <NavigationBar path={path} />
    </BrowserRouter>
  </React.StrictMode >,

  document.getElementById('root')
);

And then in NavigationBar class i set state in constructor state of redirectToPath to true if prop.path!==undefined.

and in render method i call redirect only once if needed:

render() {
        if (this.state.redirectToPath) {
            this.setState({ redirectToPath: false });
            return (<Redirect to={this.props.path}/>)
        }
return ( regular render....)

So when i want to redirect from spring app to localhost/reactModule.

  1. redirect to localhost/reactModule
  2. error handler catch no handler exception and redirect to localhost/index.html?path=reactModule
  3. index.html gets path and add it as property to its child
  4. Child element redirects correctly if path exists

Upvotes: 0

Shailendra
Shailendra

Reputation: 9102

Your react app is a bunch of javascript/css/images files and when downloaded to your browser it runs and calls the API backend written in Spring boot ( this obvisously needs CORS to be enabled). Your backend Spring boot app should usually respond with json content so directly accessing backend API via browser does not make much sense unless you want to test GET API's or API testing via tool like Postman. Remember it does not make sense to actually redirect API calls - they should just return json. However if your objective is to make sure anyone directly accessing the API via a browser should be redirected to React App then you make do as @Greenbones pointed.

Upvotes: 0

Jeff
Jeff

Reputation: 141

You should be able to solve this just by returning a redirect from your Spring controller. Something like:

@RequestMapping(value = "/path", method = RequestMethod.GET)
public void handleGet(HttpServletResponse response) {
    response.setHeader("Location", "localhost:3000/MainPage");
    response.setStatus(302);
}

Alternatively, if you like working with ResponseEntity in your controller:

@RequestMapping(value = "/path", method = RequestMethod.GET)
public ResponseEntity handleGet(HttpServletResponse response) {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Location", "localhost:3000/MainPage");    
    return new ResponseEntity(headers, HttpStatus.FOUND);
}

There's a variety of ways of doing it really, but these options should both work.

Upvotes: 1

Related Questions