복붙노트

[SPRING] AngularJS html5Mode로 봄 부팅

SPRING

AngularJS html5Mode로 봄 부팅

스프링 부팅으로 웹 응용 프로그램을 시작합니다. 간단한 메인 클래스를 사용하여 임베디드 tomcat 서버를 시작합니다 :

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

나는 그가 활성화 될 angularjs html5mode를 처리 할 수있는 방법으로 서버를 구성하려고합니다.

$locationProvider.html5Mode(true);

다른 사용자의 관련 게시물은 사용자가 루트로 리디렉션해야 함을 나타냅니다. html5 모드는 url에서 hashbag를 제거합니다. 페이지를 새로 고치면 서버가 해시를 처리하지 않는 페이지 원인을 찾지 못합니다. 참조 : AngularJS - URL 주소 $ routeProvider가 작동하지 않는 것처럼 보이고 404 오류가 발생하는 이유는 무엇입니까?

해결법

  1. ==============================

    1.나는 똑같은 문제가 있었다. 내가 아는 한, html5 모드에서 angularjs는 해시를 해결하지 않지만 pushState를 통해 추가 된 url 또는 url을 입력했습니다.

    나는 똑같은 문제가 있었다. 내가 아는 한, html5 모드에서 angularjs는 해시를 해결하지 않지만 pushState를 통해 추가 된 url 또는 url을 입력했습니다.

    문제는 PathResourceResolver가 디렉토리를 매핑하지만 파일은 매핑하지 않는다는 것입니다. 요청 된 파일을 디렉토리에서 제공하지만 URL을 다시 쓰지 않으려 고했기 때문입니다. 응용 프로그램의 경우, 브라우저 창을 새로 고치거나 http://example.com/mystate와 같은 url을 입력하면 서버에서 "/ mystate"라는 쿼리가 발생합니다. spring이 url을 모르면 404를 반환합니다. 해결책 중 하나는 index.html에 모든 가능한 상태를 여기에 매핑하는 것입니다 (소스, 웹에서 btw보기 - 멋지 네요!). 하지만 내 경우에는 안전하게 "/ **"을 index.html에 매핑 할 수 있으므로 내 솔루션은 PathResourceResolver # getResource를 재정의하는 것입니다.

    @Configuration
    @EnableConfigurationProperties({ ResourceProperties.class })
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
        @Autowired
        private ResourceProperties resourceProperties = new ResourceProperties();
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            Integer cachePeriod = resourceProperties.getCachePeriod();
    
            registry.addResourceHandler("/static/**")
                    .addResourceLocations("classpath:/static/")
                    .setCachePeriod(cachePeriod);
    
            registry.addResourceHandler("/**")
                    .addResourceLocations("classpath:/static/index.html")
                    .setCachePeriod(cachePeriod).resourceChain(true)
                    .addResolver(new PathResourceResolver() {
                        @Override
                        protected Resource getResource(String resourcePath,
                                Resource location) throws IOException {
                            return location.exists() && location.isReadable() ? location
                                    : null;
                        }
                    });
        }
    }
    
  2. ==============================

    2.이 컨트롤러를 사용하여 AngularJS 라우트를 보존하기 위해 URI를 index.html로 전달하십시오. 출처 https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii

    이 컨트롤러를 사용하여 AngularJS 라우트를 보존하기 위해 URI를 index.html로 전달하십시오. 출처 https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii

    @Controller
    public class ForwardController {
    
        @RequestMapping(value = "/**/{[path:[^\\.]*}")
        public String redirect() {
            // Forward to home page so that route is preserved.
            return "forward:/";
        }
    } 
    

    이 솔루션에서 ForwardController는 다른 컨트롤러 나 RestController에서 정의되지 않은 경로 만 전달합니다. 이미 가지고있는 경우 :

    @RestController
    public class OffersController {
    
        @RequestMapping(value = "api/offers")
        public Page<OfferDTO> getOffers(@RequestParam("page") int page) {
            return offerService.findPaginated(page, 10);
        }
    } 
    

    @RequestMapping (value = "api / offers")은 @RequestMapping (value = "/**/{[path:[^\\.]*}") 이전에 검사됩니다.

  3. ==============================

    3.내가 살 수있는 해결책을 찾았습니다.

    내가 살 수있는 해결책을 찾았습니다.

    @Controller
    public class ViewController {
    
        @RequestMapping("/")
        public String index() {
            return "index";
        }
    
        @RequestMapping("/app/**")
        public String app() {
            return "index";
        }
    }
    

    angularjs 앱은 하위 도메인 앱 아래에 있어야합니다. 원하지 않는 경우 app.subdomain.com과 같은 하위 도메인을 만들어 하위 도메인 앱에 매핑 할 수 있습니다. 이 구조를 사용하면 webjars, statis 컨텐츠 등과 충돌 할 필요가 없습니다.

  4. ==============================

    4.나에게 맞는 이전 코드의 작은 조정.

    나에게 맞는 이전 코드의 작은 조정.

    // Running with Spring Boot v1.3.0.RELEASE, Spring v4.2.3.RELEASE
    @Configuration
    @EnableConfigurationProperties({ ResourceProperties.class })
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
    @Autowired
    private ResourceProperties resourceProperties = new ResourceProperties();
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        Integer cachePeriod = resourceProperties.getCachePeriod();
    
        final String[] staticLocations = resourceProperties.getStaticLocations();
        final String[] indexLocations  = new String[staticLocations.length];
        for (int i = 0; i < staticLocations.length; i++) {
            indexLocations[i] = staticLocations[i] + "index.html";
        }
        registry.addResourceHandler(
                "/**/*.css",
                "/**/*.html",
                "/**/*.js",
                "/**/*.json",
                "/**/*.bmp",
                "/**/*.jpeg",
                "/**/*.jpg",
                "/**/*.png",
                "/**/*.ttf",
                "/**/*.eot",
                "/**/*.svg",
                "/**/*.woff",
                "/**/*.woff2"
                )
                .addResourceLocations(staticLocations)
                .setCachePeriod(cachePeriod);
    
        registry.addResourceHandler("/**")
                .addResourceLocations(indexLocations)
                .setCachePeriod(cachePeriod)
                .resourceChain(true)
                .addResolver(new PathResourceResolver() {
                    @Override
                    protected Resource getResource(String resourcePath,
                            Resource location) throws IOException {
                        return location.exists() && location.isReadable() ? location
                                : null;
                    }
                });
    }
    

    }

  5. ==============================

    5.사용자 정의 ErrorViewResolver를 제공하여 발견되지 않은 모든 자원을 기본 페이지로 전달할 수 있습니다. 이 작업을 @Configuration 클래스에 추가하기 만하면됩니다.

    사용자 정의 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;
            }
        };
    }
    
  6. ==============================

    6.드디어 spring-boot-starter-tomcat을 포함하거나 포함하지 않은 상태로 스프링 부트로 작업하는 Angular 5 응용 프로그램을 얻게되었습니다!

    드디어 spring-boot-starter-tomcat을 포함하거나 포함하지 않은 상태로 스프링 부트로 작업하는 Angular 5 응용 프로그램을 얻게되었습니다!

    /**
     * Needed for html5mode (PathLocationStrategy in Angular). Every path except api/* and resources (css, html, js, woff, etc..)
     * should be redirect to index.html and then should angular managed routes (which could be correct or non existing).
     */
    @RestController
    @RequestMapping
    public class ForwardController {
    
        @GetMapping(value = "/**/{[path:[^\\.]*}")
        public ModelAndView forward() {
            return new ModelAndView("/index.html");
        }
    }
    
  7. ==============================

    7.리소스를 구성하고 싶지만 AngularJS Html5 모드를 사용하려는 것과 비슷한 문제가 발생했습니다.

    리소스를 구성하고 싶지만 AngularJS Html5 모드를 사용하려는 것과 비슷한 문제가 발생했습니다.

    내 경우에는 내 정적 파일이 / public 경로에서 제공되었으므로 색인 작업에 다음 요청 매핑을 사용 했으므로 모두 정상적으로 작동합니다.

    @RequestMapping(value = {"", "/", "/{[path:(?!public).*}/**"}, method = GET)
    public String indexAction() {
        return "index";
    }
    
  8. ==============================

    8.난 각도 Html5Mode를 사용하는 동안 동일한 문제가있었습니다. 나를 위해 일한 해결책은 내 케이스 "/"에서 내 인덱스보기로 경로를 지정하는 web.xml에서 404에 대한 오류 페이지를 구성하는 것이 었습니다.

    난 각도 Html5Mode를 사용하는 동안 동일한 문제가있었습니다. 나를 위해 일한 해결책은 내 케이스 "/"에서 내 인덱스보기로 경로를 지정하는 web.xml에서 404에 대한 오류 페이지를 구성하는 것이 었습니다.

    <error-page>
        <error-code>404</error-code>
        <location>/</location>
    </error-page>
    

    마찬가지로 봄 부팅시 오류 페이지를 구성해볼 수도 있습니다. 참조를 위해이 링크를 확인할 수 있습니다.

    봄 부팅 및 맞춤 404 오류 페이지

  9. ==============================

    9.먼저 새로운 컨트롤러를 생성 한 후 코드를 복사하여 붙여 넣으십시오.

    먼저 새로운 컨트롤러를 생성 한 후 코드를 복사하여 붙여 넣으십시오.

    @Controller
    public class viewController {
    
     @RequestMapping(value = "/**/{[path:[^\\.]*}")
     public String redirect() {
        // Forward to home page so that route is preserved.
        return "forward:/";
     }
    
    }
    

    3 - 각도 앱에서 항목 아래 2 개를 제거합니다.

    $locationProvider.hashPrefix('!');
    $urlRouterProvider.otherwise("/");
    

    2- 각도 응용 프로그램에서는 $ locationProvider.html5Mode (true)를 추가해야합니다. 앱 경로로

    3 - index.html 파일에 http 요청 전에 기본 태그를 두는 것을 잊지 마십시오.

    <head>
    <base href="/"> /* Or whatever your base path is */
    
    //call every http request for style and other 
    ...
    </head>
    

    나를 위해 잘 작동한다.

  10. from https://stackoverflow.com/questions/24837715/spring-boot-with-angularjs-html5mode by cc-by-sa and MIT license