봄에는 index.html의 모든 루트를 캐치합니다.
리액트 라우터를 사용하여 클라이언트 측 루팅을 수행하는 리액트 기반 단일 페이지 애플리케이션용 스프링 백엔드를 개발하고 있습니다.
index.html의 합니다./api/**
.
index.html에서 index.을 src/main/resources/public/index.html
패스 " " " "/
했습니다.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/").addResourceLocations("/index.html");
}
index.html 이외의 때 등 때 항상 할 수 ./api
.
봄철에 이런 캐치올 루트를 설정하려면 어떻게 해야 하나요?
리액트 앱이 루트를 포워드 타깃으로 사용할 수 있기 때문에, 이것은 나에게 있어서 기능하게 되었다.
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{spring:\\w+}")
.setViewName("forward:/");
registry.addViewController("/**/{spring:\\w+}")
.setViewName("forward:/");
registry.addViewController("/{spring:\\w+}/**{spring:?!(\\.js|\\.css)$}")
.setViewName("forward:/");
}
}
솔직히 무한 전송 루프를 피하기 위해 이 포맷이 필요한 이유를 알 수 없습니다.
Spring Boot 앱 내에서 폴리머 기반의 PWA를 호스트하고 이미지와 같은 정적 웹 리소스와 "/api/..." 아래의 REST API를 사용하고 있습니다.클라이언트측 앱에서 PWA의 URL 루팅을 처리해 주었으면 합니다.사용법은 다음과 같습니다.
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* Ensure client-side paths redirect to index.html because client handles routing. NOTE: Do NOT use @EnableWebMvc or it will break this.
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// Map "/"
registry.addViewController("/")
.setViewName("forward:/index.html");
// Map "/word", "/word/word", and "/word/word/word" - except for anything starting with "/api/..." or ending with
// a file extension like ".js" - to index.html. By doing this, the client receives and routes the url. It also
// allows client-side URLs to be bookmarked.
// Single directory level - no need to exclude "api"
registry.addViewController("/{x:[\\w\\-]+}")
.setViewName("forward:/index.html");
// Multi-level directory path, need to exclude "api" on the first part of the path
registry.addViewController("/{x:^(?!api$).*$}/**/{y:[\\w\\-]+}")
.setViewName("forward:/index.html");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/webapp/");
}
}
이는 Angular 앱과 React 앱에서도 작동합니다.
@EnableWebMvc 회피
은 "Spring-Boot"에 를 제공합니다.src/main/resources
:
- /META-INF/리소스/
- /timeout/
- /static/
- /public/
이것과 이것 좀 보세요.
또는 @EnableWebMvc를 유지하고 addViewControllers를 덮어씁니다.
@EnableWebMvc
이 페이지를 보세요.Java Spring Boot: 앱 루트("/")를 index.html에 매핑하는 방법
@하거나 @EnableWebMvc를 다시 할 수 .addViewControllers
:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
하여 는는포 or or or or or or or를 잡습니다./
github에서 이 spring-boot-reactjs 샘플프로젝트를 보실 수 있습니다.
컨트롤러를 사용하여 원하는 작업을 수행합니다.
@Controller
public class HomeController {
@RequestMapping(value = "/")
public String index() {
return "index";
}
}
index.html
에 있다src/main/resources/templates
, react-router에 있는 .이거는 매핑이 있는 컨트롤러를 만드는 것만큼이나 간단합니다./
웹 사이트의 하위 트리는 다음과 같습니다./users/**
내 이 있다.
@Controller
public class SinglePageAppController {
@RequestMapping(value = {"/", "/users/**", "/campaigns/**"})
public String index() {
return "index";
}
}
API 호출이 이 컨트롤러에 의해 포착되지 않고 리소스가 자동으로 처리됩니다.
이 질문을 보고 답을 찾았습니다.
@Bean
public EmbeddedServletContainerCustomizer notFoundCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
}
};
}
솔루션)myurl1
,myurl2
: , ...( ) :
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
public class SinglePageAppController {
/**
* If the user refreshes the page while on a React route, the request will come here.
* We need to tell it that there isn't any special page, just keep using React, by
* forwarding it back to the root.
*/
@RequestMapping({"/myurl1/**", "/myurl2/**"})
public String forward(HttpServletRequest httpServletRequest) {
return "forward:/";
}
}
주의: 사용방법public String index()
또한 정상적으로 동작하지만 템플릿을 사용하는 경우에만 작동합니다. ,의 ,WebMvcConfigurerAdapter
을 사용하다
여기의 /api 루트를 제외한 모든 경우에 Single Page App(SPA)을 제공하는 것과 관련된 당신의 질문에 답하기 위해 저는 Petri의 답변을 수정했습니다.
SPA용 index.html이 포함된 폴리머라는 이름의 템플릿이 있습니다.따라서 /api 및 /public-api를 제외한 모든 경로를 해당 뷰로 전송해야 합니다.
WebMvcConfigurerAdapter I에서 addViewController를 덮어쓰고 정규 표현 ^(?/api/|/public-api/)을 사용했습니다.*$
이 경우 정규 표현은 ^((?/api/))입니다.*$
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{spring:^((?!/api/).)*$}").setViewName("polymer");
super.addViewControllers(registry);
}
그 결과 http://localhost 또는 http://localhost/community에 접속하여 SPA를 지원할 수 있으며 SPA가 발신하는 나머지 콜은 모두 http://localhost/public-api/posts 등에 정상적으로 라우팅됩니다.
많은 시도 끝에 다음과 같은 가장 간단한 해결책을 찾았습니다.기본적으로 처리하기가 매우 어려웠던 스프링 핸들링을 모두 우회할 수 있습니다.
@Component
public class StaticContentFilter implements Filter {
private List<String> fileExtensions = Arrays.asList("html", "js", "json", "csv", "css", "png", "svg", "eot", "ttf", "woff", "appcache", "jpg", "jpeg", "gif", "ico");
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
}
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String path = request.getServletPath();
boolean isApi = path.startsWith("/api");
boolean isResourceFile = !isApi && fileExtensions.stream().anyMatch(path::contains);
if (isApi) {
chain.doFilter(request, response);
} else if (isResourceFile) {
resourceToResponse("static" + path, response);
} else {
resourceToResponse("static/index.html", response);
}
}
private void resourceToResponse(String resourcePath, HttpServletResponse response) throws IOException {
InputStream inputStream = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream(resourcePath);
if (inputStream == null) {
response.sendError(NOT_FOUND.value(), NOT_FOUND.getReasonPhrase());
return;
}
inputStream.transferTo(response.getOutputStream());
}
}
언급URL : https://stackoverflow.com/questions/39331929/spring-catch-all-route-for-index-html
'programing' 카테고리의 다른 글
CORB(Cross-Origin Read Blocking) (0) | 2023.02.24 |
---|---|
환경 변수로 JSON 내보내기 (0) | 2023.02.24 |
Wordpress는 slug와 함께 분류법 이름을 가져옵니다. (0) | 2023.02.24 |
부정한 C# 식별자의 원인이 되는 JSON 문자열을 해석하려면 어떻게 해야 합니까? (0) | 2023.02.24 |
어레이가 php에서 비어 있으면 json_encode 함수가 중괄호 {}을(를) 반환하지 않음 (0) | 2023.02.24 |