I have made an autosuggest input field that automatically searches the database on every keypress. It works fine when i insert regular characters like letters and numbers but it gets spooky when you try start the search request with the character #. Doing that throws the error org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'long'; nested exception is java.lang.NumberFormatException: For input string: "get"
When i add some letters before the # (for example des#) it will throw an 404 page not found error and if i use the % character it will throw an 400 'unauthorized' error.
This strange behavior has probably something to do that i'm expecting a GetRequest instead of a PostRequest. If i turn it into a PostMapping i'm sure the errors will dissapear. But my question is; why is this happening? Does # have a special meaning? Why does spring seemingly try to convert # to a long value even though the pathvariable is typed as String? And why has the input string become "get" according to the error? I know that in an url # has a special meaning in that it signifies an href anchor but why should it be a special character for spring?
Heres the code of my getMapping
@GetMapping("/get/varietynames/{searchString}/{languageCode}")
public List<CropVarietyNameSelectionDTO> getCropVarietySelectionDTOBySearchString(@PathVariable("searchString") @NotBlank @Pattern(regexp = "^[A-Za-z0-9]+$", message = "Search input only allows for letters and numbers")
@Size(min = 1, max = 40, message = "Search input cannot exceed 40 characters") String searchString, @PathVariable("languageCode") String languageCode){
return seedService.getCropVarietySelectionDTOBySearchString(searchString,languageCode);
}
Edit
Request on the frontend side is:
private basePath:string = this.apiUrl + "/seed";
getCropVarietySelectionDTOBySearchString(searchString: string):Observable<CropVarietyNameSelectionDTO[]>{
return (searchString && (searchString.trim().length > 0)) ? this.http.post<CropVarietyNameSelectionDTO[]>(this.basePath + "/get/varietynames/" + this.languageService.getCodeOfPreferredLanguage(), searchString) : Observable.of([]);
}
this.apiUrl = localhost:4200
That is not the correct way or option to use @PathVariable annotation which indicates that a method parameter should be bound to a URI template variable. You need to use @RequestParam annotation which indicates that a method parameter should be bound to a web request parameter. You can see this answer that is a @RequestParam vs @PathVariable
@GetMapping("/get/varietynames")
public List<CropXXXDTO> getXXXXXhString(@RequestParam @NotBlank
@Pattern(regexp = "^xx+$", message = "xxxxx")
@Size(min = 1, max = 40, message = "xxxxx") String searchString,
@RequestParam(required = false, defaultValue = "EN") String languageCode){
return seedService.getXXXXtring(searchString, languageCode);
}
Then you can check the URL
by following way:
/get/varietynames?searchString=XXXXX&languageCode=EN