Springboot / Angular 2 - HTML5 URL 처리 방법
간단한 질문이라고 생각합니다만, 검색에서 정답을 찾거나 올바른 용어를 사용할 수 없었습니다.
는 업업을 .Angular2
★★★★★★★★★★★★★★★★★」Springboot
「」입니다.Angular
, 하다, 하다, 하다 같은 을 사용합니다.localhost:8080\dashboard
★★★★★★★★★★★★★★★★★」localhost:8080\dashboard\detail
.
가능하면 경로를 해시로 사용하지 않았으면 합니다.Angular 문서에 명시된 대로:
라우터의 providerRouter 함수는 LocationStrategy를 PathLocationStrategy로 설정하여 기본전략으로 합니다.필요에 따라 부트스트래핑 프로세스 중에 오버라이드를 사용하여 Hash Location Strategy로 전환할 수 있습니다.
그리고...
거의 모든 Angular 2 프로젝트에서 기본 HTML 5 스타일을 사용해야 합니다.사용자가 이해하기 쉬운 URL을 생성합니다.또한 나중에 서버 측 렌더링을 수행할 수 있는 옵션이 유지됩니다.
는 했을 때localhost:8080\dashboard
봄이러한 매핑은 없습니다.
Whitelabel Error Page
There was an unexpected error (type=Not Found, status=404).
No message available
에는 모든 를 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★localhost:8080\api
내 모든 정전기 밑의localhost:8080\app
어떻게 에게 이 수 app
예외?
Angular2와 Boot 중 어느 쪽이 더 좋은 솔루션이 있습니까?
Spring Boot 어플리케이션(버전1 및 2)에서는 스태틱리소스는 1개소에 있어요
src/main/resources/static
static
스프링 부츠
봄 MVC를 이용하다
봄 자바
는 장장을 실장하고 .WebMvcConfigurer
addResourceHandlers()
싱글을 추가하다 ResourceHandler
의 류류 the the ResourceHandlerRegistry
는 모든 , 는 " " " 를 합니다.classpath:/static/
리소스 위치 값으로 지정합니다(물론 필요에 따라 다른 값을 추가할 수도 있습니다).
.PathResourceResolver
override " " " anonymous anonymous anonymous anonymous"getResource(String resourcePath, Resource location)
.
그리고 자원을 반환하는 규칙은 다음과 같습니다.리소스가 존재하여 읽을 수 있는 경우(즉, 파일), 반환한다. 않으면로는 「」를 합니다.index.html
HTML 5 URL 입니다.
Spring Boot 1.X 어플리케이션:
★★org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
길이에요.
는 is스 of of of of of of 입니다.WebMvcConfigurer
빈 메서드를 사용하는 인터페이스를 사용하면 서브패킷이 관심 있는 메서드만 덮어쓸 수 있습니다.
다음은 전체 코드입니다.
import java.io.IOException;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.resource.PathResourceResolver;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**/*")
.addResourceLocations("classpath:/static/")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
@Override
protected Resource getResource(String resourcePath,
Resource location) throws IOException {
Resource requestedResource = location.createRelative(resourcePath);
return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
: new ClassPathResource("/static/index.html");
}
});
}
}
Spring Boot 2.X 응용 프로그램:
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
더 이상 사용되지 않습니다.
직접 구현WebMvcConfigurer
이 방법은 아직 인터페이스이지만 기본 방식(Java 8 베이스라인에 의해 가능)이 적용되어 어댑터가 필요 없이 직접 구현할 수 있게 되었습니다.
다음은 전체 코드입니다.
import java.io.IOException;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**/*")
.addResourceLocations("classpath:/static/")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
@Override
protected Resource getResource(String resourcePath,
Resource location) throws IOException {
Resource requestedResource = location.createRelative(resourcePath);
return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
: new ClassPathResource("/static/index.html");
}
});
}
}
몇 가지 코멘트에 대처하기 위한 EDIT:
스태틱 리소스를 다른 위치에 저장하는 사용자:src/main/resources/static
, var args 파라미터의 값을 변경합니다.addResourcesLocations()
결과적으로
예를 들어, 양쪽 모두에 스태틱리소스가 있는 경우static
또,public
폴더(시도되지 않음):
registry.addResourceHandler("/**/*")
.addResourceLocations("classpath:/static/", "/public")
솔루션을 하나 준비했습니다.ViewController
Spring Boot에서 Angular로 요청을 전송합니다.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ViewController {
@RequestMapping({ "/bikes", "/milages", "/gallery", "/tracks", "/tracks/{id:\\w+}", "/location", "/about", "/tests","/tests/new","/tests/**","/questions","/answers" })
public String index() {
return "forward:/index.html";
}
}
여기에서는 모든 angular2("/bikes", "/milages", "/gallery", "/tracks/{id:\w+}", "/location", "/about", "/tests/new", "/tests/*", "/quests"/quests"/ans"를 SPA로 리다이렉트했습니다.맛있게 드세요!
커스텀 ErrorViewResolver를 지정하면 발견되지 않은 모든 리소스를 메인 페이지로 전송할 수 있습니다.필요한 것은 @Configuration 클래스에 다음 명령어를 추가하는 것뿐입니다.
@Bean
ErrorViewResolver supportPathBasedLocationStrategyWithoutHashes() {
return new ErrorViewResolver() {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
return status == HttpStatus.NOT_FOUND
? new ModelAndView("index.html", Collections.<String, Object>emptyMap(), HttpStatus.OK)
: null;
}
};
}
다음과 같은 방법으로 Angular에 매핑되지 않은 모든 데이터를 전송할 수 있습니다.
@Controller
public class ForwardController {
@RequestMapping(value = "/**/{[path:[^\\.]*}")
public String redirect() {
// Forward to home page so that route is preserved.
return "forward:/";
}
}
출처 : https://stackoverflow.com/a/44850886/3854385
Angular용 스프링 부트서버는 API 호출을 사용하는 게이트웨이 서버이기도 합니다./api
각진 페이지 앞에 로그인 페이지가 없으면 다음과 같은 것을 사용할 수 있습니다.
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
/**
* This sets up basic authentication for the microservice, it is here to prevent
* massive screwups, many applications will require more secuity, some will require less
*/
@EnableOAuth2Sso
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Override
public void configure(HttpSecurity http) throws Exception {
http
.logout().logoutSuccessUrl("/").and()
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.anyRequest().permitAll().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
Error Page Registrar 를 직접 실장하는 것만으로 간단하게 할 수 있습니다.
@Component
public class ErrorPageConfig implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
}
}
그러면 요청이 index.html로 전송됩니다.
@Controller
@RequestMapping("/")
public class MainPageController {
@ResponseStatus(HttpStatus.OK)
@RequestMapping({ "/" })
public String forward() {
return "forward:/";
}
}
다음 3가지 단계를 수행해야 합니다.
독자적인 Tomcat Embedded Servlet Container Factory bean을 구현하고 Rewrite Valve를 설정합니다.
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; ... import org.apache.catalina.valves.rewrite.RewriteValve; ... @Bean TomcatEmbeddedServletContainerFactory servletContainerFactory() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); factory.setPort(8080); factory.addContextValves(new RewriteValve()); return factory; }
응용 프로그램의 WEB-INF 디렉토리에 rewrite.conf 파일을 추가하고 개서 규칙을 지정합니다.다음으로 angular 어플리케이션에서 사용하고 있는 rewrite.conf 콘텐츠의 예를 나타냅니다(기본적으로 모든 것을 index.html로 리다이렉트 합니다.스프링 부트를 사용하여 정적 웹 콘텐츠를 처리하거나 Rewrite Cond 규칙에서 컨트롤러를 필터링해야 합니다).
RewriteCond %{REQUEST_URI} !^.*\.(bmp|css|gif|htc|html?|ico|jpe?g|js|pdf|png|swf|txt|xml|svg|eot|woff|woff2|ttf|map)$ RewriteRule ^(.*)$ /index.html [L]
라우팅 선언에서 useHash를 삭제합니다(또는 false로 설정합니다).
RouterModule.forRoot(routes)
또는
RouterModule.forRoot(routes, {useHash: false})
index.html을 사용하여 모든 Angular 루팅을 전송합니다.base href 포함.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ViewController {
@RequestMapping({ "jsa/customer","jsa/customer/{id}",})
public String index() {
return "forward:/index.html";
}
}
내 경우 jsa는 base href입니다.
그냥 오래된 필터로 했어요.
public class PathLocationStrategyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if(request instanceof HttpServletRequest) {
HttpServletRequest servletRequest = (HttpServletRequest) request;
String uri = servletRequest.getRequestURI();
String contextPath = servletRequest.getContextPath();
if(!uri.startsWith(contextPath + "/api") &&
!uri.startsWith(contextPath + "/assets") &&
!uri.equals(contextPath) &&
// only forward if there's no file extension (exclude *.js, *.css etc)
uri.matches("^([^.]+)$")) {
RequestDispatcher dispatcher = request.getRequestDispatcher("/");
dispatcher.forward(request, response);
return;
}
}
chain.doFilter(request, response);
}
}
ㅇㅇㅇㅇ에서web.xml
:
<web-app>
<filter>
<filter-name>PathLocationStrategyFilter</filter-name>
<filter-class>mypackage.PathLocationStrategyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PathLocationStrategyFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
</web-app>
패스를 포인트API)를 합니다.index.html
UI 리 ui ui ui ui ui ui :
1 - 예: 1 " - " UI " " 예예 ( " ) 。/app/page1
,/app/page2
,/app/page3
,/app/page2/section01
등 ) 。
2 - 파일(HTML, 을 2개의 파일에 - UI 파일(HTML, JS, CSS 등)에 카피합니다./resources/static/
3 - service 3 - 。index.html
「」로 시작하는 에 대해/app/
다음과 같은 컨트롤러에 의해 제어됩니다.
@Controller
public class SPAController {
@RequestMapping(value = "/app/**", method = RequestMethod.GET)
public ResponseEntity<String> defaultPath() {
try {
// Jar
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("/static/index.html");
// IDE
if (inputStream == null) {
inputStream = this.getClass().getResourceAsStream("/static/index.html");
}
String body = StreamUtils.copyToString(inputStream, Charset.defaultCharset());
return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(body);
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error in redirecting to index");
}
}
@GetMapping(value = "/")
public String home(){
return "redirect:/app";
}
}
언급URL : https://stackoverflow.com/questions/38516667/springboot-angular2-how-to-handle-html5-urls
'programing' 카테고리의 다른 글
Oracle이 제약 조건을 발견하다 (0) | 2023.04.06 |
---|---|
아이디 대신 우편명으로 우편물을 받다 (0) | 2023.04.06 |
TypeScript의 '확장'과 '실장'의 차이점은 무엇입니까? (0) | 2023.04.06 |
커스텀 디렉티브의 ng-change 구현 방법 (0) | 2023.04.06 |
구텐베르크에 블록을 '수동'(프로그래밍 방식으로) 삽입하려면? (0) | 2023.04.06 |