Spring框架和AngularJs的圆形视图路径异常

Posted

技术标签:

【中文标题】Spring框架和AngularJs的圆形视图路径异常【英文标题】:Circular view path exception with Spring framework And AngularJs 【发布时间】:2017-07-02 18:56:52 【问题描述】:

我对 Spring Boot 框架工作比较陌生。我在 Angular 中构建了一个基本的 Web 应用程序,连接了 Spring Boot 并连接到了 Mongodb。该应用程序允许用户添加待办事项列表并注册该网站。当应用程序启动时,它会将存储在 mongodb 中的 todolist 返回到视图。用户可以注册,详细信息存储在 Mongo 存储库中。

当我添加并实现 Spring Security 时,我收到了错误消息

Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)

我想要发生的是,当 webapp 加载时,我希望 index.html 被注入 todo.html。然后,如果用户登录,他们将被定向到另一个页面或某些 Ui 功能可用。目前我被困在这个圆形视图路径循环中。

我查看了不同的答案,但我仍然对究竟是什么导致问题感到困惑。我相信它在 WebSecurityConfig 类中

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter

  @Autowired
  UserDetailsService userDS;

  @Override
  protected void configure(HttpSecurity http) throws Exception

    http
      .authorizeRequests()
        .antMatchers("/api/todos/*").permitAll()
        .anyRequest().authenticated()
        .and()
      .formLogin()
        .loginPage("/login")
        .permitAll()
        .and()
      .logout()
        .permitAll();
  

  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 

    auth
      .userDetailsService(userDS);

  

  @Override
  protected UserDetailsService userDetailsService() 
      return userDS;
    

AuthUserDetailsS​​ervice

@Repository
public class AuthUserDetailsService implements UserDetailsService 
  @Autowired
  private UserRepository users;
  private org.springframework.security.core.userdetails.User userdetails;

  @Override
  public UserDetails loadUserByUsername(String username)
      throws UsernameNotFoundException 
    // TODO Auto-generated method stub

    boolean enabled = true;
    boolean accountNonExpired = true;
    boolean credentialsNonExpired = true;
    boolean accountNonLocked = true;

    todoapp.models.User user = getUserDetail(username);

    userdetails = new User (user.getUsername(),
                user.getPassword(),
                enabled,
                accountNonExpired,
                credentialsNonExpired,
                accountNonLocked,
                getAuthorities(user.getRole())
                );

    return userdetails;
  
  public List<GrantedAuthority> getAuthorities(Integer role) 

    List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
    if (role.intValue() == 1) 
      authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
     else if (role.intValue() == 2) 
      authList.add(new SimpleGrantedAuthority("ROLE_USER"));
    

    return authList;
  

  private todoapp.models.User getUserDetail(String username)

      todoapp.models.User user = users.findByUsername(username);


    return user;
  

TodoController

@RestController
@RequestMapping("/api/todos")
public class TodoController 

    @Autowired
    TodoRepository todoRepository;

    @RequestMapping(method=RequestMethod.GET)
    public List<Todo> getAllTodos() 
        return todoRepository.findAll();
    

    @RequestMapping(method=RequestMethod.POST)
    public Todo createTodo(@Valid @RequestBody Todo todo) 
        return todoRepository.save(todo);
    

    @RequestMapping(value="id", method=RequestMethod.GET)
    public ResponseEntity<Todo> getTodoById(@PathVariable("id") String id) 
        Todo todo = todoRepository.findOne(id);
        if(todo == null) 
            return new ResponseEntity<Todo>(HttpStatus.NOT_FOUND);
         else 
            return new ResponseEntity<Todo>(todo, HttpStatus.OK);
        
    

    @RequestMapping(value="id", method=RequestMethod.PUT)
    public ResponseEntity<Todo> updateTodo(@Valid @RequestBody Todo todo, @PathVariable("id") String id) 
        Todo todoData = todoRepository.findOne(id);
        if(todoData == null) 
            return new ResponseEntity<Todo>(HttpStatus.NOT_FOUND);
        
        todoData.setTitle(todo.getTitle());
        todoData.setCompleted(todo.getCompleted());
        Todo updatedTodo = todoRepository.save(todoData);
        return new ResponseEntity<Todo>(updatedTodo, HttpStatus.OK);
    

    @RequestMapping(value="id", method=RequestMethod.DELETE)
    public void deleteTodo(@PathVariable("id") String id) 
        todoRepository.delete(id);
    


资源控制器

@Configuration
public class ResourceController extends WebMvcConfigurerAdapter
   @Override
      public void addViewControllers(ViewControllerRegistry registry) 
          registry.addViewController("/").setViewName("index");
          registry.addViewController("/api/todos").setViewName("home");
          registry.addViewController("/register").setViewName("register");
          registry.addViewController("/login").setViewName("login");
      

我们将不胜感激。

这是项目布局。

【问题讨论】:

【参考方案1】:

您忘记在视图名称中添加 .html

registry.addViewController("/").setViewName("app/views/index.html");
registry.addViewController("/api/todos").setViewName("app/views/home.html");
registry.addViewController("/register").setViewName("app/views/register.html");
registry.addViewController("/login").setViewName("app/views/login.html");

Spring Boot 注册了一个ResourceHttpRequestHandler,它能够解析static 文件夹下的静态资源。 因为您将login 设置为视图名称ResourceHttpRequestHandler 尝试加载显然不存在的static/login。 将其更改为 app/views/login.html,以便 static/login 变为 static/app/views/login.html

【讨论】:

我将 registry.addViewController 更改为以下内容。 registry.addViewController("/").setViewName("static/views/index.html"); 我也将项目结构添加到问题中。 太棒了。更新了我的答案 我按照指示更改了我的 addViewController 路由。我不再收到圆形视图路径错误,但网页现在显示错误。此应用程序没有显式映射 /error,因此您将其视为后备。 2017 年 2 月 14 日星期二 16:06:49 GMT 出现意外错误(类型=未找到,状态=404)。没有可用的消息 另外,当运行 localhost:8080 时,url 是 localhost:8080/login

以上是关于Spring框架和AngularJs的圆形视图路径异常的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring MVC 测试避免“圆形视图路径”异常

循环视图路径错误 Spring boot

将 Spring MVC 应用程序从 JSP 迁移到 AngularJS

Django + AngularJS:没有使用普通 URL 和视图的 Django REST 框架的类 REST 端点?

带有 AngularJs 的 Ionic 框架:模态是不是可以与启动模态的视图具有相同的控制器?

听一个复选框并在谷歌地图上显示/隐藏圆形(AngularJS)