【问题标题】:404 Error when trying to Post or Get RestController when webservice and client are on a different port当 web 服务和客户端位于不同端口时,尝试发布或获取 RestController 时出现 404 错误
【发布时间】:2016-10-10 17:40:11
【问题描述】:

我正在使用 Spring-boot 和 Angular 2;前端和后端在不同的端口上运行。当我使用 Advanced REST Client(谷歌浏览器插件)检查 URL 时,http://localhost:4000/user/register 得到 404,当我在前端输入信息时没有任何反应。

网络服务配置:

@Configuration
public class CorsConfig {

    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class CorsFilter implements Filter {

        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest)req;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Allow-Headers", "origin, x-requested-with, accept, Authorization, Content-Type");
            response.setHeader("Access-Control-Max-Age", "3600");
            if (!request.getMethod().equals("OPTIONS")) {
                try {
                    chain.doFilter(req, res);
                } catch (IOException e) {
                    System.out.println("IO Exception in CorsFilter: "+e);
                    e.printStackTrace();
                } catch (ServletException e) {
                    System.out.println("Servlet Exception is CorFilter "+e);
                    e.printStackTrace();
                }
            }
        }

        public void init(FilterConfig filterConfig) {}

        public void destroy() {}

    }

}

以上是我如何配置后端。

我正在尝试注册一个新的user(Angular 2)

@Injectable()
export class RegisterService {

    constructor (private http:Http) { }

    sendUser (newUser: RegisterModel) {
        let url = "http://localhost:4000/user/register";
        let header = new Headers({'Content-Type': 'application/json'});

        return this.http.post(url, JSON.stringify(newUser),{headers: header});
    }
}

它是组件:

@Component ({
    moduleId: module.id,
    selector: 'register',
    templateUrl: './register.html'
})
export class RegisterComponent {

    newUser: RegisterModel = new RegisterModel();

    constructor (private registerService: RegisterService){

    }

    onSubmit() {
        this.registerService.sendUser(this.newUser).subscribe(
            data => {
                this.newUser = new RegisterModel();
                console.log("New user was created.")
            },
            error => console.log(error)
        );
    }
}

安心服务

@RestController("/user")
public class UserController {

    @Autowired
    UserService userService;


    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public User registerUser(@RequestBody User user){

        System.out.println("YAY-----------"+user.getFirstName());
        return userService.save(user);
    }



}

什么都没有打印出来,也没有给出错误。

在我的 application.properties 我有

server.port=4000

页面呈现,但后端似乎没有响应。

如果有人想看,我也将其发布在 GIT 中。

Git Hub link

---------------------更新1--------

我已将我的 SecurityConfig 更新为:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/").permitAll()
            .anyRequest().authenticated().and()
            .formLogin().loginPage("/").permitAll().and()
            .logout().permitAll();

        http.authorizeRequests().antMatchers("/user/register")
            .permitAll().anyRequest().anonymous();

        http.authorizeRequests().antMatchers("/")
            .permitAll().anyRequest().authenticated();

        http.formLogin().loginPage("/")
            .permitAll().and().logout().permitAll();

    }

}

2)我还删除了frontend目录下的pom file

结果:当我使用Advanced REST client(谷歌浏览器插件)时,我现在得到一个The requested URL can't be reached

在 GIT 上更新了它。

【问题讨论】:

  • 你的项目在 github 上的父 pom 包含错误。 (1) type 必须是“pom”,而不是“war”。 (2) 第 56 行包含使 xml 无效的垃圾文本“rc.6”。 + 单元测试在编译时失败 (RequestDemoApplicationTests.java)
  • + 你的 angular/npm 项目还继承了 spring boot 并定义了 spring-boot-plugin(+后端项目中的那个),这导致 spring boot 寻找 2 个主要类并将其扔到 build时间:“无法找到主要课程”。解决方案:你的前端项目是一个javascript项目,为什么它有一个带有spring-boot依赖的pom?
  • 在出现错误之前,您的项目的 pom 中有很多需要修复的地方。当然,您没有使用 maven 构建项目,而只是从 intellij 构建/运行它?
  • + 你的 application.properties(在 github 上)不包含 server.port=4000
  • 我修复了所有问题,以便构建。然后我能够启动它(“mvn spring-boot:run”+“npm start”)。我发布了您的问题的答案。

标签: angular spring-boot


【解决方案1】:

安全配置重定向到 root => 404 错误

我假设您在通过身份验证之前发送register 请求?您的安全配置将所有请求重定向到 /,它不在后端提供。所以它没有被找到,你会收到一个404

您的安全配置

这是您的WebSecurityConfigurerAdapter 的安全配置:

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

允许匿名发送register 请求

您可以将安全配置更改为此,让register 在被验证之前通过:

http.authorizeRequests().antMatchers("/user/register")
    .permitAll().anyRequest().anonymous();

http.authorizeRequests().antMatchers("/")
   .permitAll().anyRequest().authenticated();

http.formLogin().loginPage("/")
    .permitAll().and().logout().permitAll();

基本上允许anonymous发送注册请求。

项目中的其他错误(也在comments 部分突出显示)

  • 父 pom 必须是 'pom' 类型
  • 父 pom 的第 56 行包含错误
  • 您的前端 pom 不应包含 spring-boot(这会导致 spring boot 查找 2 个主类并失败)

cmets 后更新

(1) 用户控制器

您的 UserController 没有定义任何映射。你误用了@RestController("/user"),其实应该是:

@RestController
@RequestMapping("/user")
public class UserController {

(2) 安全配置

您在 SecurityConfig 中仍然保留了之前的配置:

protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/").permitAll()
        .anyRequest().authenticated().and()
        .formLogin().loginPage("/").permitAll().and()
        .logout().permitAll();

    http.authorizeRequests().antMatchers("/user/register")
        .permitAll().anyRequest().anonymous();

    http.authorizeRequests().antMatchers("/")
        .permitAll().anyRequest().authenticated();

    http.formLogin().loginPage("/")
        .permitAll().and().logout().permitAll();    
}

将其更改为:

protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();

    http.authorizeRequests().antMatchers("/user/register")
        .permitAll().anyRequest().anonymous();

    http.authorizeRequests().antMatchers("/")
        .permitAll().anyRequest().authenticated();

    http.formLogin().loginPage("/")
        .permitAll().and().logout().permitAll();
}

第一行禁用 csrf (Cross-Site Request Forgery)。现在,我对这个主题的知识不够给你解释,但如果你不禁用它,你会得到 403 禁止响应。我建议您禁用它,等您当前的问题得到解决后再返回。


就是这样,您的后端将接收并响应 /user/register 请求(我可以在控制台中看到前端的日志:“新用户已创建”。

10 月 18 日编辑

我克隆了您的项目并且它有效。以下是我执行的确切步骤:

  • 打开终端并输入git clone https://github.com/drewjocham/AngularIssue.git
  • 修复了 RequestDemoApplicationTests 的包从 test.java.com.requestcom.request
  • AngularIssue\backend 中打开了一个终端
  • 输入mvn clean install
  • 输入mvn spring-boot:run(后端现在运行)
  • 打开另一个终端到AngularIssue\frontend
  • 输入npm install
  • 输入npm start(前端现在运行)
  • 在 chrome 中打开 http://localhost:3000
  • 在 chrome 中打开了 inspect->console 视图
  • 填写注册表并点击提交
  • Chrome 的控制台显示New user was created.
  • 后端的终端显示YAY-----------a

【讨论】:

  • 非常感谢您的努力! 1)我进行了上述更改,并通过谷歌 REST 客户端生成了The requested URL can't be reached.... 2)我删除了前端的 pom 文件。 3)我现在通过嵌入式tomcat在intellij中运行项目是的。 4)不知道为什么applications.properties在我做出改变并反映在git上时没有更新。 5) 感谢您的建议,我正在 git 上更新我的项目。
  • 你能用你的错误更新你的问题吗?您在哪里看到“无法访问请求的 URL”。错误 ?什么网址导致此错误?在您的浏览器中,您可以在“检查”视图中看到什么?您在 Spring Boot 控制器中看到“Yay”日志了吗?
  • 现在更新问题,我看到高级 REST 客户端的错误(谷歌插件和谷歌浏览器)。我在 IDE 的控制台中看不到任何内容。
  • 更新完成。非常感谢您的帮助,非常感谢!
  • 更新了答案——见答案的第二部分“cmets 后更新”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多