what does this BindingResult error mean in spring mvc? - spring-mvc

I have a login button in my site's ui, which when clicked goes to the /login address, which is handled by the controller below. But when I click on this button, the following error occurs. What is the reason? It is written that BindingResult must come after the model, which is the same in my code. I also saw this link, but it did not help.
#RequestMapping(value = "login", method = {RequestMethod.GET, RequestMethod.POST})
public String showLogin(#RequestParam(required = false) String error,
#RequestParam(required = false) String logout,
#Valid #RequestParam(required = false) #NotBlank(message = "username should not be blank") String username,
#Valid #RequestParam(required = false) #NotBlank(message = "password should not be blank") String password,
Model model,
BindingResult result) {
...
}
error:
An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the #RequestBody or the #RequestPart arguments to which they apply: public java.lang.String com.isoft.controllers.LoginController.showLogin(java.lang.String,java.lang.String,java.lang.String,java.lang.String,org.springframework.validation.BindingResult,org.springframework.ui.Model)

Related

Mismatch in #PathVariable resolving

Let's suppose to have this method signature:
#RequestMapping(value = "/verifyusers/{site}/{users}", method = RequestMethod.GET)
#ResponseBody
public List<String> verifyUser(
#PathVariable("site") String site, #PathVariable("users") String[] users) {
...
}
Receving a request like GET /verifyusers/AOUD/farmaci.rain,farmaci.postacuti
we get: site="AOUD" and users = [farmaci.rain, farmaci] that is we lose the second part of second String after dot ("postacuti")
I think it's the fault of org.springframework.util.AntPathMatcher ...
Use below code to prevent truncation of parameter after ' . '
#RequestMapping(value = "/verifyusers/{site}/{users:.+}", method = RequestMethod.GET)
#ResponseBody
public List<String> verifyUser(
#PathVariable("site") String site, #PathVariable("users") String[] users) {
...
}
Note: {users:.+}

Can I set a default value for a path variable at RequestMapping in SpringMVC?

Is it possibile to set a default value to a #PathVariable in SpringMVC?
#RequestMapping(value = {"/core/organization/{pageNumber}", "/core/organization"} , method = RequestMethod.GET)
public String list(#PathVariable Integer pageNumber, ModelMap modelMap) {
In this case. If I access the page without pageNumber I want to set a default value to 1.
Is that possible?
There's no way to to set a default value, but you can create two methods:
#RequestMapping(value = {"/core/organization/{pageNumber}", "/core/organization"} , method = RequestMethod.GET)
public String list(#PathVariable Integer pageNumber, ModelMap modelMap){
...
}
#RequestMapping(value = {"/core/organization/", "/core/organization"} , method = RequestMethod.GET)
public String list(#PathVariable Integer pageNumber, ModelMap modelMap){
Integer pageNumber=defaultvalue;
...
}
I'm not sure if this is what you want, but if you want a default showing up in swagger, you can use #ApiImplicitParams/#ApiImplicitParam to annotate the function, with a defaultValue and paramType="path" specified.

Return JSON for ResponseEntity<String>

I have a method in my controller that should returns a String in JSON. It returns JSON for non primitive types:
#RequestMapping(value = "so", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> so() {
return new ResponseEntity<String>("This is a String", HttpStatus.OK);
}
The curl response is:
This is a String
The root of the problem is that Spring (via ResponseEntity, RestController, and/or ResponseBody) will use the contents of the string as the raw response value, rather than treating the string as JSON value to be encoded. This is true even when the controller method uses produces = MediaType.APPLICATION_JSON_VALUE, as in the question here.
It's essentially like the difference between the following:
// yields: This is a String
System.out.println("This is a String");
// yields: "This is a String"
System.out.println("\"This is a String\"");
The first output cannot be parsed as JSON, but the second output can.
Something like '"'+myString+'"' is probably not a good idea however, as that won't handle proper escaping of double-quotes within the string and will not produce valid JSON for any such string.
One way to handle this would be to embed your string inside an object or list, so that you're not passing a raw string to Spring. However, that changes the format of your output, and really there's no good reason not to be able to return a properly-encoded JSON string if that's what you want to do. If that's what you want, the best way to handle it is via a JSON formatter such as Json or Google Gson. Here's how it might look with Gson:
import com.google.gson.Gson;
#RestController
public class MyController
private static final Gson gson = new Gson();
#RequestMapping(value = "so", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> so() {
return ResponseEntity.ok(gson.toJson("This is a String"));
}
}
#RequestMapping(value = "so", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String so() {
return "This is a String";
}
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
public ResponseEntity<?> ApiCall(#PathVariable(name = "id") long id) throws JSONException {
JSONObject resp = new JSONObject();
resp.put("status", 0);
resp.put("id", id);
return new ResponseEntity<String>(resp.toString(), HttpStatus.CREATED);
}
An alternative solution is to use a wrapper for the String, for instances this:
public class StringResponse {
private String response;
public StringResponse(String response) {
this.response = response;
}
public String getResponse() {
return response;
}
}
Then return this in your controller's methods:
ResponseEntity<StringResponse>

#Validated outside of #RequestMapping

Is it possible to run #Validated after the #RequestMapping method has started? The reason is that I need to modify the #ModelAttribute before actually validating it.
Ideally something like this.
#RequestMapping(value = "/doSomething",
method = RequestMethod.POST)
public final String DoSomething(
#ModelAttribute(value = "myobject") final MyObject myobject) {
//.... do some processing on myobject
//.... now validate
BindingResult bindingResult = validate(myobject);
//...
And a method like this
private final BindingResult validate(
#Validated(value = {Group1.class, Group2.class}) MyObject myobject) {
return bindingResult //somehow return a BindingResult
}
Use your own custom Validator
http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/validation.html#validation-binder

Return value of Controller should be ignored

For test reasons I'd like to have a method signature in a spring-mvc-controller with a return value which should be ignored by spring:
#RequestMapping(value = "/{uuid}", params = "question", method = RequestMethod.POST)
#ResponseBody
public IAnswer saveAnswer(UiAnswer json, #PathVariable String uuid, #RequestParam("question") String question, HttpServletResponse response) {}
It's a post-request where the controller receives data and just responses with response.setStatus(HttpServletResponse.SC_OK); if everything went fine.
With #ResponseBody it dies in a internal server error 500
Without #ResponseBody spring tries to resolve the view
With void as the return value, it works fine
Can I tell spring to ignore my returned object?
Thanks!
#RequestMapping(value = "/{uuid}", params = "question", method = RequestMethod.POST)
#ResponseBody
public void saveAnswer(UiAnswer json,
#PathVariable String uuid,
#RequestParam("question") String question,
HttpServletResponse response) {
doSaveAnswer(json, uuid, question, response);
}
protected IAnswer doSaveAnswer(UiAnswer json,
String uuid,
String question,
HttpServletResponse response) {
// your original code here
}
Then unit-test doSaveAnswer().

Resources