Spring Controller method being called again with the own method result - java

This is my controller:
#Controller
#RequestMapping("/area")
public class AreaController {
#RequestMapping("/{id}")
public String getPage(#PathVariable("id") int id){
return "asd3333";
}
}
and this is what I get when I access http://localhost:8080/area/1:
Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "asd3333"]
I tested this random return just to show what is happening...
The method is beeing called first with the #PathVariable = 1 from the request, and then right after that, is called again with the whethever the method resulsts, in this case, it tries to pass the #PathVariable = "asd3333".
I have NO IDEA of what tha heck is happening, pls help

Sounds very strange indeed. I will start with a question
#RequestMapping("/{id}")
public String getPage(#PathVariable("id") int id){
return "asd3333";
}
Does this method need to be called for all method types (Get, Post, Delete, ...). If no try to restrict with a specific method call.
ex
#RequestMapping(value = "/{id}", method = POST)
GOTCHA.
Also add this to the method because you return a simple string
#RequestMapping("/{id}")
#ResponseBody
public String getPage(#PathVariable("id") int id)
Also if you don't plan to use this API as a web MVC application but instead as a rest API backend switch from #Controller to #RestController.

Related

How to do post request on a method returns integer

in the below example, I am trying to know how in he below code, i am trying to perform POST request given the method initVar ().
I tried to do the post request as follows:
http://localhost:8080/root/initVar/id/2->error
http://localhost:8080/root/initVar/id?2->error
but it does not work when i return Int data type form the method.
please let me know how to fix this error.
please note that this method return Int
code:
#RestController
#RequestMapping("root")
class Controller1 {
val sayHiLazy by lazy {
"hi from get"
}
#GetMapping(value = "/sayHi")
#ResponseBody
fun sayHi() : String {
return sayHiLazy
}
#PostMapping("/initVar/id")
#ResponseBody
fun initVar(#PathVariable id : Int) : Int {
return 11
}
}to use spring annotation with koltin in intellij. i used spring annotation with java projects in intellij. but for koltin, it does not work.
in the below example, HelloController is underlined with red and i recived the following werror:
classes annotated with #Configurations cannto be implicily subclassed and must be final
please let me know how to fi
Controller1
#SpringBootConfiguration
#RequestMapping("/app")
public class HelloController {
#RequestMapping(value = "/hello")
fun SayHello(): String {
return "success"
}
}
If You want to use #PathVariable, You have to do something like this:
#RequestMapping(value="/stuff/{id}")
#ResponseBody
public String doStuff(#PathVariable("id") int id){
return "id="+id;
}
You usually write POST method without variables at the end. For such scenarios You should use PUT - https://restfulapi.net/rest-put-vs-post/
I'm not sure if You can return plain integer as a response, but You could optionally wrap your integer into String - String.valuOf(id);
Regards

How to write a controller method's signature when url has a parameter data after the slash?

In PHP there is the possibility to recognize a parameter in the address bar by passing it in the controller's method ; for example :
http://192.168.2.49/papsp/index.php/meeting/modif/3
In this example the data 3 is taken as parameter value for the meeting controller's method modif :
public modif($key) { ... }
So how to proceed analogically in Spring ?
You need to use the #RequestMapping annotation, along with #PathVariable with your method param. And your url will be like this /meeting/modif/{key}.
Here's how should be your code:
#RequestMapping(value = "/meeting/modif/{key}", method = RequestMethod.POST)
public void modif(#PathVariable int key) {

How Spring controller handles parameter implicitly?

I am a newbie on Spring framework and maybe this is an easy question.
I have a link as follows and attempt Spring controller handles the value"201610061023" of this link.However,my code did not work.
I know this value can be attached as a parameter or pathvariable in path but I just curious can I pass this value implicitly?
Thank you very much.
201610061023
#RequestMapping(value = "/Order")
public String requestHandlingMethod(#ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
Spring will not handle the title of the link simply because the title of the link will not be sent by the browser. To send it you can either:
add the value as parameter: 201610061023
add the value as path variable: 201610061023
add a JavaScript that will copy the title onClick into the href or send the generated URL with document.location. This can be automated, but it's pretty uncommon.
Your a-tag is wrong, you need to submit the id, there is no implicit way to submit the link-text (except a lot of java script code)!
201610061023
#RequestMapping(value = "/Order/{orderId}")
public String requestHandlingMethod(#PathVariable("orderId") long orderId, #ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
or
201610061023
#RequestMapping(value = "/Order")
public String requestHandlingMethod(#RequestParam("orderId") long orderId, #ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
See #RequestParam vs #PathVariable for the difference between this two approaches

Spring Rest Controller, Path Variables on an overriden method's arguement

I have a controller annotated with #RestController and it implements an interface:
public interface ContratEndpoint {
String ROOT = "/api/contrats";
String GET_CONTRAT = "";
String GET_CONTRAT_PER_PK = "/{idContrat}";
#RequestMapping(value = GET_CONTRAT)
Contrat getContrat(#RequestParam(value = "contratId")Long contratId);
#RequestMapping(value = GET_CONTRAT_PER_ID)
ExtContrat getContratById(#PathVariable("idContrat") Long idContrat);
}
The controller:
#RestController
#RequestMapping(value = ContratEndpoint.ROOT)
public class ContratController implements ContratEndpoint {
//Injecting Services....
#Resource
private Mapper mapper;
#Override
public Contrat getContrat(Long contratId) {
return mapper.map(contratService.get(contratId),Contrat.class);
}
#Override
public ExtContrat getContratById(#PathVariable("idContrat") Long idContrat){
Preconditions.checkArgument(idContrat !=null);
return mapper.map(contratService.get(idContrat),ExtContrat.class);
}
.The above Code works just fine.
. But For the first inherited method , I didn't have to annotate arguments with #RequestParam and it worked just fine.
As for the second method I tried at first :
#Override
public ExtContrat getContratById(Long idContrat){
Preconditions.checkArgument(idContrat !=null);
return mapper.map(contratService.get(idContrat),ExtContrat.class);
}
. I expected the same behaviour Like the first Method, But i was wrong and the code ended up firing an IllegalArgumentException because of the check in ligne Preconditions.checkArgument(idContrat!=null).
My question is what is so specific about #PathVariable that i've missed ?
Or is it just something is wrong with my approach?
Thanks.
There is difference between Request param and path variable,seee below post that you can confirm with your uri the cause for the exception :
#PathVariable is to obtain some placeholder from the uri (Spring call it an URI Template) — see Spring Reference Chapter 16.3.2.2 URI Template Patterns
#RequestParam is to obtain an parameter — see Spring Reference Chapter 16.3.3.3 Binding request parameters to method parameters with #RequestParam
Assume this Url http://localhost:8080/SomeApp/user/1234/invoices?date=12-05-2013 (to get the invoices for user 1234 for today)
#RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
public List<Invoice> listUsersInvoices(
#PathVariable("userId") int user,
#RequestParam(value = "date", required = false) Date dateOrNull) {
...
}

Spring MVC, deserialize single JSON?

How can I easily separate JSON values that are sent in the same request?
Given that I POST a JSON to my server:
{"first":"A","second":"B"}
If I implement the following method in the Controller:
#RequestMapping(value = "/path", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public void handleRequest(#RequestBody String input) {
// ...
}
then the input parameter will constitute a String with the entire JSON object, {"first":"A","second":"B"}. What I really want is two separate Strings (or a String and an int whichever is suitable for the particular request) with just the two values (other key / value pairs that the client may send should be ignored).
If the strings were sent as request parameters instead of JSON request body it would be simple:
#RequestMapping(value = "/path", method = RequestMethod.POST)
public void handleRequest(#RequestParam("first") String first,
#RequestParam("second") String second) {
// ...
}
I know that I can create a simple bean class that can be used in conjunction with the #RequestBody annotation that will contain both A and B when used, but it seems like a detour, since they will have different purposes inside the web app.
Dependencies:
org.springframework : spring-web : 3.1.0.RELEASE
org.codehaus.jackson : jackson-mapper-asl : 1.9.3
POJO
public class Input {
private String first;
private String second;
//getters/setters
}
...and then:
public void handleRequest(#RequestBody Input input)
In this case you need Jackson to be available on the CLASSPATH.
Map
public void handleRequest(#RequestBody Map<String, String> input)
I have written a custom WebArgumentResolver that does exactly this, combined with a custom annotation.
I don't have the source available to me now, but basically I annotated my method like this:
#RequestMapping(value = "/path", method = RequestMethod.POST)
public void handleRequest(#JsonField("first") String first, #JsonField("second") String second) {
// ...
}
Then my JsonFieldWebArgumentResolver checks if the method parameter is annotated with JsonField, and if it is it extracts the actual type from the parameter (not quite straight-forward it turns out if you want to handle generic parameters as well, such as List<String> or List<Pojo>), and invokes Jackson's JsonParser manually to create the correct type. It's a shame I can't show you any code, but that's the gist of it.
However, that solution is for Spring MVC 3.0, and if you are using 3.1 I think you will be better off using a custom HandlerMethodArgumentResolver instead. But the idea should be the same.

Categories

Resources