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를 이용하다 
봄 자바
는 장장을 실장하고 .WebMvcConfigureraddResourceHandlers()싱글을 추가하다 ResourceHandler의 류류 the the ResourceHandlerRegistry
는 모든 , 는 " " " 를 합니다.classpath:/static/리소스 위치 값으로 지정합니다(물론 필요에 따라 다른 값을 추가할 수도 있습니다).
.PathResourceResolver override " " " anonymous anonymous anonymous anonymous"getResource(String resourcePath, Resource location).
그리고 자원을 반환하는 규칙은 다음과 같습니다.리소스가 존재하여 읽을 수 있는 경우(즉, 파일), 반환한다. 않으면로는 「」를 합니다.index.htmlHTML 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")
솔루션을 하나 준비했습니다.ViewControllerSpring 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.htmlUI 리 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 |