I am trying to do a post request with body and header. Below are some of the variations I have gone through, but for the most part I am getting error on the server saying that the parameter, 'key', was not passed in.
I tried this api in the postman and it's working there. This is how I have defined the method header in Java/Spring Boot:
@RequestMapping(value = "/getIssue", method = RequestMethod.POST)
public IssuePojo getIssue(@RequestParam("key") String key, HttpServletRequest request) {
Below are my angular's variations:
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});
}
It seems that the body is being sent:
But this is the error I got:
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
HttpParams()用于将查询字符串参数添加到请求URL(如果需要),然后首先检查是否在开发者工具请求中添加了该参数,否则api端出现问题
OK, my understanding is that you have an JS/Angular 7 front-end. It's talking to a Java/Spring Boot back end, which in turn queries Jira:
Angular SpringBoot Jira
--------- (1) ----------- (2) ----------
(service) --> (controller) --> (Jira API)
<-- <--
(4) (3)
Correct so far?
It's it sounds like you can successfully query Jira with Postman (request 2, response 3), correct?
The problem is that your get HTTP 400: "Required String parameter 'key' is not present"
when Angular queries Spring Boot (request 1), correct?
That's what I was trying to ask in my comments above. The problem is clearly that your message payload, "key=WJC-7", isn't valid JSON. So the request fails.
Based on what you've shared, I'm making a lot of "assumptions" here. Nevertheless:
SUGGESTION:
Have Angular create the object: let obj = { key: key };
, just like you were doing in the first place.
Make sure it's complete (I imagine the Jira API needs more than just a "key").
Make sure the Angular object you're sending matches - field-for-field - the Java object the Spring Boot controller is expecting. Spring Boot should automatically serialize/deserialize in JSON.
Have Angular send the object (as "data"). Your "message payload" != "msg headers".
Be SURE to examine the payloads being sent and received each step of the way (1, 2, 3 and 4 above). You can do this with Fiddler, with Wireshark, or with trace logging.
'Hope that helps!
PS: Here's a hypothetical example of a Java Spring Boot controller that an Angular client might invoke:
...
@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();
}
...
And here is the corresponding example Java "Todo" object:
public class Todo {
private long id;
private String username;
private String description;
private Date targetDate;
private boolean isDone;
...
Use this HHTP service class to send parameters in body and you can send in headers too
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); }; } }
So the key is 'Content-Type': 'application/json',
Since I'm sending json, then on the server side its expecting to map it to an Object. I managed to get it to work with string as well, but then I have to parse the string myself on the server which is not what I'm looking to do.
So 'Content-Type': 'text/plain',
=> maps to => @RequestBody String key
And 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
=> maps to => @RequestParam String key, @RequestParam String test,
And so the post call from Angular will look like this:
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.