带有主体和标题的Angular 7发布请求

时间:2019-01-30 04:27:39

标签: angular rest spring-boot

我正在尝试使用body和header进行发布请求。以下是我经历的一些变化,但是在大多数情况下,我在服务器上收到错误消息,指出未传入参数“ key”。

我在邮递员中尝试了这个api,并且在那儿工作。这就是我在Java / Spring Boot中定义方法标头的方式:

@RequestMapping(value = "/getIssue", method = RequestMethod.POST)
public IssuePojo getIssue(@RequestParam("key") String key, HttpServletRequest request) {

以下是我的角度变化:

public getJiraIssue(key: string): Observable<any> {

    let headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'Authorization': this.idToken });
  let options = { headers: headers };

    const paramsA = new URLSearchParams();
    paramsA.set('key', key);
    let params = new HttpParams().append('key', key);
    // return this.http.post(this.urlEnvironment.jiraGetIssue(), params, this.getHeaders());
    console.log("headers: ", this.getHeaders());
    // let obj = {
    //   key: key
    // }

    var headersA = new Headers();
    headers.append('Authorization', this.idToken);

    let body = new HttpParams()
    .set('key', key);

    return this.http.post(this.urlEnvironment.jiraGetIssue(), body, {headers: headers});
    // return this.http.post(this.urlEnvironment.jiraGetIssue(), null, {headers: this.getHeaders(), params: params});
  }

似乎正在发送尸体:

enter image description here

但这是我得到的错误:

timestamp: "2019-01-30T04:30:40.721+0000", status: 400, error: "Bad Request",…}
error: "Bad Request"
message: "Required String parameter 'key' is not present"
path: "/jira/getIssue"
status: 400
timestamp: "2019-01-30T04:30:40.721+0000"
trace: "org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'key' is not present

4 个答案:

答案 0 :(得分:2)

HttpParams()用于将查询字符串参数添加到请求URL(如果需要),然后首先检查是否已将其添加到开发工具请求中(如果存在),则api端出现问题

答案 1 :(得分:1)

好的,我的理解是您拥有JS / Angular 7前端。它正在与Java / Spring Boot后端通信,后者又查询Jira:

    Angular       SpringBoot         Jira
   --------- (1)  ----------- (2) ----------
   (service) --> (controller) --> (Jira API)
             <--              <--
             (4)              (3)

到目前为止正确吗?

听起来您可以使用Postman成功地查询Jira(请求2,响应3),对吗?

问题是当Angular查询Spring Boot(请求1)时,您得到HTTP 400: "Required String parameter 'key' is not present",对吗?

这就是我在上面的评论中要问的问题。问题显然是您的消息有效负载“ key = WJC-7”不是有效的JSON。因此请求失败。

根据您分享的内容,我在这里做了很多“假设”。不过:

建议:

  1. 让Angular创建对象let obj = { key: key };,就像刚开始时一样。

  2. 确保它是 complete (我想Jira API不仅需要“钥匙”)。

  3. 确保您要发送的Angular对象与Spring Boot控制器期望的Java对象匹配。 Spring Boot应该会自动在JSON中序列化/反序列化。

  4. 让Angular发送对象(作为“数据”)。您的“邮件有效负载”!=“ msg标头”。

  5. 请确保 来检查发送和接收的有效载荷的每一步(上面的1、2、3和4)。您可以使用Fiddler,Wireshark或跟踪日志记录来完成此操作。

'希望有帮助!

PS: 这是Angular客户端可能调用的Java Spring Boot控制器的假设示例:

...
@RestController
@CrossOrigin(origins = "http://localhost:4200")
public class TodoResource {

    @Autowired
    private TodoHardcodedService todoService;

    // GET All todos
    @GetMapping("/users/{username}/todos")
    public List<Todo> getAllTodos(@PathVariable String username) {
        return todoService.findAll();
    }
...

这是相应的示例Java“ Todo”对象:

public class Todo {
    private long id;
    private String username;
    private String description;
    private Date targetDate;
    private boolean isDone;
    ...

答案 2 :(得分:0)

enter image description here使用此HHTP服务类在正文中发送参数,也可以在标题中发送

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable, empty } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';


@Injectable({
  providedIn: 'root'
})
export class HttpService {
  constructor(private http: HttpClient) {
  }

  private getHeaders(headersConfig?: object): HttpHeaders {
    return new HttpHeaders({
      'Content-Type': 'application/json',
      ...headersConfig,
    });
  }

  get(url: string, params: HttpParams = new HttpParams(), headers: Object): Observable<any> {
    let finalHeaders = this.getHeaders();
    if (headers) {
      for (let key in headers) {
        finalHeaders = finalHeaders.append(key, headers[key]);
      }
    }
    return this.http.get(
      url,
      { headers: finalHeaders, params }
    ).pipe(timeout(10000)).pipe(catchError(this.handleError('Get request')));
  }

  put(url: string, body: Object = {}, headers: Object): Observable<any> {
    let finalHeaders = this.getHeaders();
    if (headers) {
      for (let key in headers) {
        finalHeaders = finalHeaders.append(key, headers[key]);
      }
    }
    return this.http.put(
      url,
      body,
      { headers: finalHeaders }
    ).pipe(timeout(10000)).pipe(catchError(this.handleError<any>('put request')));
  }

  post(url: string, body: Object = {}, headers: Object): Observable<any> {
    let finalHeaders = this.getHeaders();
    if (headers) {
      for (let key in headers) {
        finalHeaders = finalHeaders.append(key, headers[key]);
      }
    }
    return this.http.post(
      url,
      body,
      { headers: finalHeaders }
    ).pipe(timeout(10000)).pipe(catchError(this.handleError<any>('post request')));
  }

  /**
 * Handle Http operation that failed.
 * Let the app continue.
 * @param operation - name of the operation that failed
 * @param result - optional value to return as the observable result
 */
  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      return empty();//of(result as T);
    };
  }
}

答案 3 :(得分:0)

因此密钥为'Content-Type': 'application/json',,因为我正在发送json,所以在服务器端,它希望将其映射到Object。我设法使它也可以与字符串一起使用,但是随后我必须自己在服务器上解析该字符串,这不是我想要做的。

所以'Content-Type': 'text/plain', =>映射到=> @RequestBody String key

'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', =>映射到=> @RequestParam String key, @RequestParam String test,

因此来自Angular的帖子调用将如下所示:

const httpBody = new HttpParams()
      .set('key', 'key')
      .set('test', 'test');
    return this.http.post(endPoint, httpBody, this.getArgHeaders());

  private getArgHeaders(): any {
      const httpOptions = {
        headers: new HttpHeaders({
          'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
        })
      };
      return httpOptions;
  }