Spring Загрузка с помощью AngularJS html5Mode

Я запускаю свое веб-приложение с загрузкой spring. Он использует простой основной класс для запуска встроенного сервера tomcat:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

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

}

Я хочу настроить сервер так, чтобы он мог обрабатывать angularjs html5mode, который будет активирован с помощью

$locationProvider.html5Mode(true);

Соответствующие публикации от других пользователей показывают, что вам нужно перенаправить на root. режим html5 удаляет hashbag с URL-адреса. Если вы обновите страницу, сервер не найдет страницу, потому что он не обрабатывает хэш. смотрите: AngularJS - Почему при изменении адреса URL $routeProvider не работает, и я получаю ошибку 404

Ответы

Ответ 1

Я нашел решение, с которым я могу жить.

@Controller
public class ViewController {

    @RequestMapping("/")
    public String index() {
        return "index";
    }

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

Приложение angularjs должно находиться под поддоменом. Если вы не хотите, чтобы вы создали подобный поддомен, такой как app.subdomain.com, который отображается в вашем субдоменном приложении. С этой конструкцией у вас нет конфликтов с webjars, содержимым statis и т.д.

Ответ 2

У меня была такая же проблема. Насколько мне известно, в режиме html5 angularjs не разрешают хеш, а вводят url или url, добавленные через pushState.

Проблема заключалась в том, что каталоги карт PathResourceResolver, а не файлы. Поскольку он предназначен для обслуживания запрошенных файлов из каталога, но не для перезаписи URL-адресов. Для приложения это означает, что если вы обновите окно браузера или введите url как http://example.com/mystate, он запросит "/mystate" с сервера. Если spring не знают URL-адреса, они возвращают 404. Одно из решений - это отображение любого возможного состояния в index.html, например здесь (< источник href= "http://info.michael-simons.eu/2014/04/15/spring-boot-as-a-backend-for-angularjs/" rel= "noreferrer" > , btw посмотрите на webjars - это здорово!). Но в моем случае я могу смело сопоставить "/**" с 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;
                    }
                });
    }
}

Ответ 3

Используйте этот контроллер для пересылки URI в index.html для сохранения маршрутов AngularJS. Источник 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 пересылает только пути, которые не определены ни в других Controller, ни 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:[^\\.]*}")

Ответ 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

Вы можете перенаправить все не найденные ресурсы на свою основную страницу, предоставив пользовательский 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

Наконец-то я получил приложение Angular 5, работающее с spring с помощью или без spring-boot-starter-tomcat как provided (embedded) или нет!

/**
 * 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

Я просто столкнулся с аналогичной проблемой, когда я хотел настроить ресурсы, и в то же время я хотел использовать режим AngularJS Html5.

В моем случае мои статические файлы были отправлены из маршрута /public, поэтому я использовал следующее сопоставление запроса в моем действии индекса, и все это прекрасно работает.

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

Ответ 8

У меня была та же проблема при использовании angular Html5Mode. Решение, которое сработало для меня, состояло в том, чтобы настроить страницу ошибок для 404 в web.xml, назначив путь к моему указателю в моем случае "/".

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

Аналогично, вы можете попробовать настроить страницу с ошибкой в ​​ spring загрузке. для справки, вы можете проверить эту ссылку.

Spring загрузочная и пользовательская страница ошибок 404

Ответ 9

1- сначала вы создаете новый контроллер, затем копируете и вставляете простой код ниже

@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- Не забудьте поместить базовый тег перед любым запросом http в вашем файле index.html.

<head>
<base href="/"> /* Or whatever your base path is */

//call every http request for style and other 
...
</head>

у меня это нормально работает

Ответ 10

Я хотел бы отослать вас к ответу на вопрос такого же типа.

fooobar.com/info/1685425/...