【问题标题】:Fetching and Posting data to a rest microservice获取数据并将数据发布到 REST 微服务
【发布时间】:2017-12-04 12:28:55
【问题描述】:

我正在尝试使用创建的 Rest 微服务来实现 HTTP 服务 GET 和 POST。

我能够从我的 Rest 微服务中获取数据。

但我无法发出 POST 请求。

下面是我的 Rest 微服务代码

WebController.java

package com.central.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.central.model.Users;
import com.central.repository.UsersRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@RestController
public class WebController {
    private static final String NULL = null;
    @Autowired
    UsersRepository userRepo;

    @CrossOrigin(origins = "http://localhost:4200")
    @RequestMapping("/checkUsers")
    public String checkLogin() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        List<Users> useObj = (List<Users>) userRepo.findAll();
        return (mapper.writeValueAsString(useObj));
    }

    @CrossOrigin(origins = "http://localhost:4200")
    @RequestMapping(value = "/checkByCredential", method = RequestMethod.POST)
    public String checkLoginByName(@RequestBody Users user) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Users useObj1 = userRepo.findByUsernameAndPassword(user.username, user.password);
        return (mapper.writeValueAsString(useObj1));
    }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { BasicService } from './basic.service';

@NgModule({
  declarations  : [ AppComponent],
  imports       : [BrowserModule,HttpModule,FormsModule ],
  providers     : [BasicService],
  bootstrap     : [AppComponent]
})

export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { BasicService } from './basic.service';

@Component({
  selector: 'app-root',
  template: `<h1>{{ title }}</h1>
                <div style="margin-left:50px; height: 200px; overflow: auto;"> 
                 <table>
                     <tr><td>Username</td>&emsp;&emsp;<td>Password</td></tr>
                     <tr *ngFor= " let item of data">
                 <td>{{ item.username }}</td>&emsp;&emsp;<td>{{ item.password }}</td>
                 </tr>
                 </table>
                </div>


      <h2>Login</h2>
        <form role="form">
          <div ng-control-group="credentials">
            <label for="username">Username</label>
            <input
              type="text"
              #username
              id="username"
              ng-control="username"
              required>

            <label for="password">Password</label>
            <input
              type="password"
              #password
              id="password"
              ng-control="password"
              required>
          </div>
          <button (click)="checkByCredential(username,password)">Login</button>
        </form>`
})


export class AppComponent {
  title: string;
  data: any;

  constructor(private MyService: BasicService) {
    this.title = "Angular Service";

    this.MyService.GetUsers()
      .subscribe(users => { this.data = users });
  }

  checkByCredential(username: string, password: string) {
    this.MyService.checkByCredential(username, password).subscribe(users => { this.data = users });
  }
}

basic.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class BasicService {
  constructor(private http: Http) { }

  GetUsers() {
    return this.http.get('http://localhost:8080/checkUsers')
      .map(result => result.json());
  }

  checkByCredential(username: string, password: string) {
    const user = { username: username, password: password };
    return this.http
      .post('http://localhost:8080/checkByCredential', user)
      .map(result => result.json());
  }
}

当我通过表单提交数据时,我在控制台中收到此错误,如下图所示

但是当我尝试使用用户名和密码发出 Post 请求时,使用我的邮递员,我能够取回如下图所示的数据

任何机构都可以帮我解决 Angular 2 中的 Post 请求

在我的框架中更新后更新的屏幕截图

【问题讨论】:

  • 你能在邮递员中检查请求参数,并将它与你从 Angular 应用程序发出的请求进行比较
  • 确实,考虑到Spring返回的是400(错误请求),请求参数肯定有差异。还要检查 Spring 启动应用程序的日志以及浏览器中调用的完整响应,这通常可以很好地指出问题所在。
  • 非常感谢您的回复..好的,我会尝试这样做
  • 此错误是由您的框架生成的...您应该首先检查 chrome 上的网络选项卡并检查您的请求正文以确保它与您期望的相符。根据您服务中的代码,我想它会的。接下来,您在控制台中看到,您的服务器实际上正在给您一条错误消息,您应该展开它以便我们可以看到它是什么。
  • 好的,我会编辑我的问题

标签: angular spring-boot


【解决方案1】:

您从您的服务中获得了 400,因为您实际上并没有向您的服务器发送值。

这一行:

<button (click)="checkByCredential(username,password)">Login</button>

是有问题的。这2个变量是模板变量,指的是实际的输入元素,而不是输入元素的值,所以你需要这样做:

<button (click)="checkByCredential(username.value,password.value)">Login</button>

这应该在那个时候起作用。虽然我建议切换到响应式表单或 ngModel 作为长期解决方案。

至于调试,使用 console.log、chrome 上的网络选项卡,在这种情况下,甚至由您的服务器框架生成的错误消息都会立即向您准确地显示出了什么问题。

类似这样的:

checkByCredential(username: string, password: string) {
    console.log(username, password);
    this.MyService.checkByCredential(username, password).subscribe(users => { this.data = users });
}

会立即告诉您您没有得到预期值。

此外,在 chrome 中的网络选项卡上,您可以查看您发送的实际请求正文并确保它没有格式错误。

最后,如果您仔细查看返回的 400 错误(顺便说一句,400 总是意味着用户输入错误),它会显示一条特定的错误消息,可能会为您提供关于正在发生的事情的线索。

您的次要错误是因为您试图使用 ngFor 来迭代一个对象,这是不允许的,您只能将 ngFor 与数组一起使用。您真正的问题是这设计不佳,您尝试在同一元素中显示主列表和单个详细项目。您应该重新设计您的页面,以便您的“已检查用户”和“用户列表”是不同的显示元素。但是为了测试,你可以像这样登录到控制台:

this.MyService.checkByCredential(username, password).subscribe(users => console.log(users));

【讨论】:

  • 但现在我收到此错误“AppComponent.html:5 ERROR Error: Error trying to diff '[object Object]'。只允许使用数组和可迭代对象”
  • 您收到该错误是因为您尝试对“数据”进行 ngFor 并且数据是一个对象,您只能将 ngFor 与数组一起使用。您可以将其设为数组或不使用 ngFor。
  • 但我这样做是为了获取数据,即用户名和密码,只是放入视图的模板
  • ngFor 用于模板中的迭代数组,您尝试显示的数据不是数组。
  • 那么没有ngFor怎么办?
【解决方案2】:

我遇到了同样的问题。该问题是由跨域资源共享 (CORS) 引起的。我创建了一个代理文件来将流量从localhost:4200 重定向到我的spring localhost(在你的情况下是localhost:8080)。

在你的情况下,我建议像这样创建一个proxy.conf.json 文件:

{
  "/": {
    "target": "http://localhost:8080",
    "secure": false
  }
}

.. 并将代码中的绝对路径更改为相对路径,例如

return this.http
   .post('http://localhost:8080/checkByCredential', user) 
   .map(result => result.json()
)}

到:

return this.http
   .post('/checkByCredential', user) 
   .map(result => result.json()
)}

您可以使用以下命令运行您的 Angular 应用程序(启用代理):

ng serve --proxy-config proxy.conf.json

您的项目结构如下:


你的 WebController 也太复杂了;您正在序列化为 JSON,但这不是必需的。

package com.central.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.central.model.Users;
import com.central.repository.UsersRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

    @RestController
    public class WebController {
        private static final String NULL = null;
        @Autowired
        UsersRepository userRepo;

        @CrossOrigin(origins = "http://localhost:4200")
        @GetMapping("/checkUsers")
        public List<Users> checkLogin() {
            return userRepo.findAll();
        }

        @CrossOrigin(origins = "http://localhost:4200")
        @PostMapping(value = "/checkByCredential")
        public Users checkLoginByName(@RequestBody Users user) throws Exception {
            return userRepo.findByUsernameAndPassword(user.username, user.password);
        }
    }

我认为从/到 JSON 的解析出了点问题。

不要忘记删除映射方法!例如,改变这个

return this.http
   .post('http://localhost:8080/checkByCredential', user) 
   .map(result => result.json()
)}

到:

return this.http.post('http://localhost:8080/checkByCredential', user)

【讨论】:

  • 非常感谢您的回复..我会试试这个
  • "代理配置文件 C:\Angular\httprest\proxy.conf.json 不存在。"
  • 你需要在根目录下创建proxy.conf.json
  • @Heena 不,不是src,而是在package.json 文件旁边
  • 我尝试在 app 文件夹中创建它,但同样的错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多