1

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

4
  • How are you calling this URL? Show the calling code. In general a # is used for a client-side anchor and isn't send to the server at all. So unless you are encoding it properly you are calling the wrong URL. Commented Oct 28, 2019 at 9:16
  • @M.Deinum see my edit Commented Oct 28, 2019 at 20:35
  • 1
    The URL you are calling isn't the URL you are mapping. If I look at your javascript the languageCode comes first not the searchString. Also you should be encoding the searchString before sending it. When posting something with a # it is either client side anchor or interpreted as a html entity code (which is numeric by default). So you should really be escaping/encoding your search string before using it. Commented Oct 29, 2019 at 8:17
  • @M.Deinum sorry I already turned it into a post request, the code used to look different. It used get instead of post and it had searchString as a path variable Commented Oct 29, 2019 at 18:02

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

ah yes i could have also used @RequestParam. Thx for the headsup

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.