programing

Springboot / Angular 2 - HTML5 URL 처리 방법

abcjava 2023. 4. 6. 20:44
반응형

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가지 단계를 수행해야 합니다.

  1. 독자적인 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;
      }
    
  2. 응용 프로그램의 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]
    
  3. 라우팅 선언에서 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

반응형