it-roy-ru.com

Пружинная загрузка с перенаправлением с одной страницы angular2

У меня есть приложение на одну страницу angular с пружинной загрузкой. Это выглядит следующим образом

src
  main
  Java
    controller
       HomeController
       CustomerController
       OtherController
  webapp
    js/angular-files.js
    index.html

Spring boot по умолчанию корректно работает с папкой webapp и обслуживает файл index.html.

То, что я хочу сделать, это

1) Для каждого локального REST запроса нет начиная с/api перезаписать и перенаправить по умолчанию на webapp/index.html. Я планирую обслуживать что-нибудь/API для контроллеров пружин.

2) Есть ли способ добавить все контроллеры к api, чтобы мне не приходилось каждый раз писать api.

например.

@RequestMapping("/api/home") can write shorthand in code  @RequestMapping("/home")

или же

@RequestMapping("/api/other-controller/:id") can write shorthand  @RequestMapping("/other-controller/:id")

Изменить .. Больше примечаний, чтобы лучше объяснить выше

Я ищу каждый запрос API, например. 1) http: // localhost: 8080/api/home сохранить api с api и решить исправить контроллер и вернуть json.

Однако, если кто-то вводит URL-адрес как http: /// localhost/some-url или http: /// localhost/some-other/123/url Тогда он будет служить index.html и сохраните URL.

enter image description here

Альтернативные способы сделать это - попробуйте добавить #ErrorViewResolver Springboot/Angular2 - Как обрабатывать URL-адреса HTML5?

8
Robbo_UK

Для каждого локального REST запроса не начинается с перезаписи/api и перенаправляется в webapp/index.html по умолчанию. Я планирую подать что-нибудь/API для пружинных контроллеров.

Обновление 15/05/2017

Позвольте мне перефразировать ваш запрос для других читателей. (Поправьте меня, если неправильно поняли)

Фон
Использование Spring Boot и обслуживание статических ресурсов из classpath

Требование
Все запросы 404non api должны быть перенаправлены на index.html.

NON API - означает запросы, в которых URL не начинается с /api.
API - 404 должен бросить 404 как обычно.

Пример ответа
/api/something - скинет 404
/index.html - будет сервер index.html
/something - будет перенаправлен на index.html 

Мое решение

Пусть Spring MVC генерирует исключения, если какой-либо обработчик недоступен для данного ресурса.

Добавить следующее к application.properties

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

Добавьте ControllerAdvice следующим образом

@ControllerAdvice
public class RedirectOnResourceNotFoundException {

    @ExceptionHandler(value = NoHandlerFoundException.class)
    public Object handleStaticResourceNotFound(final NoHandlerFoundException ex, HttpServletRequest req, RedirectAttributes redirectAttributes) {
        if (req.getRequestURI().startsWith("/api"))
            return this.getApiResourceNotFoundBody(ex, req);
        else {
            redirectAttributes.addFlashAttribute("errorMessage", "My Custom error message");
            return "redirect:/index.html";
        }
    }

    private ResponseEntity<String> getApiResourceNotFoundBody(NoHandlerFoundException ex, HttpServletRequest req) {
        return new ResponseEntity<>("Not Found !!", HttpStatus.NOT_FOUND);
    }
}

Вы можете настроить сообщение об ошибке, как вам нравится.

Есть ли способ префикс всех контроллеров с API, чтобы мне не приходилось каждый раз писать API.

Для этого вы можете создать BaseController и установить путь RequestMapping равным /api

Пример

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/api")
public abstract class BaseController {}

Расширьте эту BaseController и убедитесь, что вы не аннотируете дочерний класс с помощью @RequestMapping

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FirstTestController extends BaseController {
    @RequestMapping(path = "/something")
    public String sayHello() {
        return "Hello World !!";
    }

}

Предыдущий ответ

Вы можете создать Filter, который перенаправляет на /index.html, если путь запроса не начинается с /api.

// CODE REMOVED. Check Edit History If you want.
14
ansh

Попробуйте это вместо

@SpringBootApplication
@RestController
class YourSpringBootApp { 

    // Match everything without a suffix (so not a static resource)
    @RequestMapping(value = "/**/{path:[^.]*}")       
    public String redirect() {
        // Forward to home page so that route is preserved.
        return "forward:/";
    }
}
10
Eduardo Eljaiek

Если вы устали пытаться решить эту проблему, следуя такому количеству противоречивых решений - смотрите здесь !!

После долгих по часам попыток следовать всем разбросанным советам из десятков переполнения стека и постов в блогах, я наконец нашел минимальное приложение PURE с пружинной загрузкой + angular 6, которое всегда перенаправляет на index.html после обновления на страница без полномочий root, поддерживающая все ваши пути к конечной точке REST API. Нет @EnableWebMvc, нет @ControllerAdvice, нет изменений в application.properties, нет пользовательских ResourceHandlerRegistry изменений, просто простота:

Очень важная предпосылка

Вы * должны * включить выходные данныеng build в папку Spring resources/static. Вы можете сделать это с помощью maven-resources-plugin. Узнайте здесь: Копирование нескольких каталогов ресурсов в независимые целевые каталоги с помощью maven

Код

@Controller
@SpringBootApplication
public class MyApp implements ErrorController {

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

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return "forward:/index.html";
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

Аргументация

  • Включение вывода ng-build в resources/static во время сборки позволяет успешно перенаправлять представление Spring ("forward:/index.html"). Кажется, что Spring не может перенаправить что-либо за пределы папки ресурсов, поэтому, если вы пытаетесь получить доступ к страницам в корне сайта, это не сработает.
  • При использовании функций по умолчанию (то есть без добавления @EnableWebMvc или изменений в application.properties) переход к / автоматически обслуживает index.html (если он был включен в папку resources/static), поэтому нет необходимости вносить изменения там.
  • При использовании функциональности по умолчанию (как указано выше) любая ошибка, возникающая в приложении весенней загрузки, направляет на /error и реализует ErrorController, переопределяет это поведение - как вы уже догадались - на index.html, что позволяет Angular взять на себя маршрутизацию.

Замечания

2
Hypothetical inthe Clavicle

Хорошо, давайте начнем с простой части вашего вопроса:

Есть ли способ префикс всех контроллеров с API, чтобы мне не приходилось каждый раз писать API?

Ответ - да, просто пометьте свой контроллер «глобальной» аннотацией @RequestMapping, например:

@RestController
@RequestMapping("/api")
public class ApiController{

   @RequestMapping("/hello") 
   public String hello(){
      return "hello simple controller";
   }

   @RequestMapping("/hello2") 
   public String hello2(){
      return "hello2 simple controller";
   }
}

В приведенном выше примере вы можете вызвать метод hello с этим URL: /api/hello

и второй метод с этим URL: /api/hello2

Так мне не нужно было отмечать каждый метод префиксом /api.

Теперь к более сложной части вашего вопроса: 

как добиться перенаправления, если запрос не начинается с префикса /api?

Вы можете сделать это, вернув HTTP-код состояния (302) Redirect, в конце концов, angularJs «говорит» REST изначально, поэтому вы не можете принудительно перенаправить код Java/Spring, как вы используете. 

Затем просто верните HTTP-сообщение с кодом состояния 302, и на вашем angularJS выполните фактическое перенаправление.

Например:

На AngularJS:

var headers = {'Content-Type':'application/json', 'Accept':'application/json'}

var config = {
    method:'GET'
    url:'http://localhost:8080/hello',
    headers:headers
};

http(config).then(
    function onSuccess(response){
        if(response.status == 302){
            console.log("Redirect");
            $location("/")
        }
}, function onError(response){
    console.log("An error occured while trying to open a new game room...");
});

На весну:

@RestController
@RequestMapping("/api")
public class ApiController{

   @RequestMapping("/hello") 
   public ResponseEntity<String> hello(){
      HttpHeaders header = new HttpHeaders();
      header.add("Content-Type", "application/json");
      return new ResponseEntity<String>("", header, HttpStatus.FOUND);
   }
}

конечно, вам нужно настроить его для вашего проекта.

0
Moshe Arad

Для всего приложения вы можете добавить контекстный путь в application.properties

server.contextPath =/API

Он добавит "/ api" к каждому запрошенному URL после http: // localhost: 8080/api/home

Для перенаправления,

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addRedirectViewController("/", "/home");
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    super.addViewControllers(registry);
}

Поместите эту кучу кода в WebMVCConfig.Java

0
Anksss

Все, что вам нужно попробовать, это поставить index.html в src/main/resources/static/

См. Пример:https://github.com/reflexdemon/shop/tree/master/src/main/resources/static

В моем package.josn я пытаюсь скопировать его в это место.

См. PackageJSON:https://github.com/reflexdemon/shop/blob/master/package.json#L14

0
reflexdemon
@Controller
public class RedirectController {
    /*
     * Redirects all routes to FrontEnd except: '/', '/index.html', '/api', '/api/**'
     */
    @RequestMapping(value = "{_:^(?!index\\.html|api).*$}")
    public String redirectApi() {
        return "forward:/";
    }
}
0
Anton

В bean-компоненте @Configuration вы можете добавить ServletRegistrationBean, чтобы сделать пружинный сервер только для запроса/api/*, тогда в контроллере его добавлять не нужно.

@Bean
public ServletRegistrationBean dispatcherRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean(
            dispatcherServlet());
    registration.addUrlMappings("/api/*");
    registration.setLoadOnStartup(1);
    registration.setName("mvc-dispatcher");
    return registration;
}
0
Jane