0

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.

  • Do I need to return the index.html page? I've tried that and failed, maybe because the index.html is located in a different module and not in the resources/static folder in my Spring module.
  • When working with React, does visiting localhost:3000 return the index.html page ?
  • If I want to redirect to localhost:3000/MainPage from my spring controller, how would I do that? React routers and switches are already setup.
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Emperor
  • 335
  • 3
  • 11
  • Not exactly sure what your question is but you may try this : https://github.com/Georges73/projet-es-highlevel-sb-react or follow this course : https://www.udemy.com/full-stack-project-spring-boot-20-react-redux/learn/lecture/11934940#overview – AchillesVan Aug 07 '19 at 15:26
  • Does this answer your question? [Redirect to an external URL from controller action in Spring MVC](https://stackoverflow.com/questions/17955777/redirect-to-an-external-url-from-controller-action-in-spring-mvc) – Mike Szyndel Dec 16 '20 at 21:49

3 Answers3

1

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.

Jeff
  • 81
  • 3
  • 11
  • Redirecting in this way is giving me a status code : Cancelled. – Emperor Aug 07 '19 at 14:09
  • Is there any way we can send some Information, lets say a string value, along with this redirection to our app? – Abhijeet srivastava Sep 03 '19 at 11:37
  • @Abhijeet I have no clue about this and is exactly what I'm looking for :p But, even if we can, how is the UI supposed to consume this data because the UI is not aware of this request in the first place. – Akhil Apr 04 '22 at 09:05
0

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.

Shailendra
  • 8,874
  • 2
  • 28
  • 37
  • I have a situation where from the React app, the user is redirected to a third service. Once he logs in to that service,the user receives some data in the headers, and gets redirected to one of my controllers. I store the data that that third service gave me, and now i want my user to continue with his life by redirecting him back to the front-end. To do that i quess i can return the index file ( which i am having issues doing), or i can try to redirect to the localhost:3000 url that @Greenbones mentioned. I am having an issue doing that as well. – Emperor Aug 07 '19 at 14:16
  • In that case I think creating a redirect response from the controller should be enough. The browser understand redirect and should reload the React App. You don't need any index.html – Shailendra Aug 07 '19 at 14:24
  • True, but like i commented on Greenbones awnser, it is giving me a Cancelled status code. – Emperor Aug 07 '19 at 14:25
  • A malformed url in redirect is also one of the reasons for cancelled request. Check here https://stackoverflow.com/questions/12009423/what-does-status-canceled-for-a-resource-mean-in-chrome-developer-tools – Shailendra Aug 07 '19 at 14:26
  • Yeah i already checked that answer. I feel like its probably more becouse the DOM element that started the request is no longer there. So i probably need a way to return the index page again. – Emperor Aug 07 '19 at 14:31
  • I faced the same problem. Did you find the solution? – Sérgio Danilo Sep 27 '20 at 11:49
0

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