问题
I want to use React on the client and Java Spring Boot on the server for REST API, both client and server are packaged together so they are hosted on the same application server.
I can already query the server APIs via the /api
path.
But (how) can I use the BrowserRouter
of react-router-dom
(Router v4) on the client instead of the HashRouter
?
I don't know Spring Boot well, but I guess I could check on the server if the route does not match /api
, then I would return the index.html
with all the react logic handling the route based on HTTP query location path?
I hope I am clear, I don't want the hash in the URL and routing must be done on the client.
回答1:
Quite old, but in general all you would need is to match api first, and then have a wildcard to match everything else and return index...
This way any deep linking would still work, by serving the root of your react app, where react router will pick up on the URL the browser holds.
Spring should handle something as simple as @RequestMapping(value = "/")
as routing everything to index. I would expect if you specify /api/ it would be more specific and take precedence.
回答2:
I finally found how to catch all GET requests and return my React app, it was deadly simple, just use a wild card *
, note that /*
will not work.
@Value("${server.servlet.context-path}")
private String contextPath;
@GetMapping("*")
public ModelAndView defaultPage(Map<String, Object> model) {
model.put("contextPath", contextPath);
return new ModelAndView("index", model);
}
In this example, the index points to this file /src/main/resources/static/index.html
回答3:
Wildcard *
has been binded to ResourceHttpRequestHandler
, it's better to keep it:
Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
If you need more management(such as server-side-render), you could define yourself's ErrorController
.
So when spring router matches nothing, spring can respond your react ssr result:
@Controller
public class ServerSideRenderrer implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping(value = "/error")
@ResponseBody
public String error(HttpServletRequest request, HttpServletResponse response) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
String original = request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
String method = request.getMethod();
if (statusCode == 404 && method.equalsIgnoreCase("GET") && original.contains("xxx")) {
response.setStatus(200);
return ssrHtmlContent;
}
return "Error handling";
}
}
来源:https://stackoverflow.com/questions/43751258/how-to-use-reacts-browserrouter-on-client-and-java-rest-api-spring-boot-on-th