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