I have a Spring MVC controller set up like so:
#RequestMapping("activityChart")
public ModelAndView activityChart(
#RequestParam(required=false, value="parent") String parent,
#RequestParam(required=false, value="expand") String[] expand,
#ModelAttribute PaginationArgs paginationargs) throws IOException {
// ... return template renderer
}
Where PaginationArgs is a two-field POJO. I want to construct a URL string that includes values for paginationargs. It's easy to do for parent and expand - activityChart?parent=foo&expand=bar&expand=baz, but what's the right way to encode a POJO's fields?
JSP takes care of this in Spring with a <form:form modelAttribute='paginationargs'> tag, but our project isn't using JSP but Jamon instead.
In the simple case parameter names should be the same as the corresponding field names of the model object. So, if PaginationArgs has fields page and size, it would be like page=1&size=10.
In more complex cases Spring can accept parameters whose names are formed as described in 5.4 Bean manipulation and the BeanWrapper.
Related
I have two mvc style endpoints returning templatefile names as view names, in the same classpath: /source and /target. The source_template has a variable which needs to be filled by contents of another template, say target_template.
#RestController
class SomeController {
#GetMapping("/source")
public String source(Model model) {
model.addAttribute("attr1", /*call endpoint /target and add the response of parsed template 'target_template' here */);
return "source_template";
}
#GetMapping("/target")
public String target(Model model) {
model.addAttribute("attr2", "good");
//may be continue the nested invocation n number of times
return "target_template";
}
}
given the source_template.html:
Hai, $attr1
and the target_template.html:
this has been a $attr2 day
having said, i invoke the url /source, I should get "Hai, this has been a good day".
I can just call the target() method directly, but that would not render the template. Or I should directly use the templating engine apis to link the template file, put the context object, parse the template and return the string , which defeats the whole purpose of spring mvc. Or I can use resttemplate, but that requires an absolute url, and performance would take a hit. So, is there any other way to do it ?
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
To my knowledge both serves the same purpose. Except the fact that #PathVariable is from Spring MVC and #PathParam is from JAX-RS. Any insights on this?
#PathVariable and #PathParam both are used for accessing parameters from URI Template
Differences:
As you mention #PathVariable is from spring and #PathParam is from JAX-RS.
#PathParam can use with REST only, where #PathVariable used in Spring so it works in MVC and REST.
QueryParam:
To assign URI parameter values to method arguments. In Spring, it is #RequestParam.
Eg.,
http://localhost:8080/books?isbn=1234
#GetMapping("/books/")
public Book getBookDetails(#RequestParam("isbn") String isbn) {
PathParam:
To assign URI placeholder values to method arguments. In Spring, it is #PathVariable.
Eg.,
http://localhost:8080/books/1234
#GetMapping("/books/{isbn}")
public Book getBook(#PathVariable("isbn") String isbn) {
#PathParam is a parameter annotation which allows you to map variable URI path fragments into your method call.
#Path("/library")
public class Library {
#GET
#Path("/book/{isbn}")
public String getBook(#PathParam("isbn") String id) {
// search my database and get a string representation and return it
}
}
for more details : JBoss DOCS
In Spring MVC you can use the #PathVariable annotation on a method argument to bind it to the value of a URI template variable
for more details : SPRING DOCS
#PathParam is a parameter annotation which allows you to map variable URI path fragments into your method call.
#PathVariable is to obtain some placeholder from the URI (Spring call it an URI Template)
Some can use #PathParam in Spring as well but value will be null when URL request is being made
Same time if We use #PathVarriable then if value is not being passed then application will throw error
#PathVariable
#PathVariable it is the annotation, that is used in the URI for the incoming request.
http://localhost:8080/restcalls/101?id=10&name=xyz
#RequestParam
#RequestParam annotation used for accessing the query parameter values from the request.
public String getRestCalls(
#RequestParam(value="id", required=true) int id,
#RequestParam(value="name", required=true) String name){...}
Note
whatever we are requesting with rest call i.e, #PathVariable
whatever we are accessing for writing queries i.e, #RequestParam
#PathParam: it is used to inject the value of named URI path parameters that were defined in #Path expression.
Ex:
#GET
#Path("/{make}/{model}/{year}")
#Produces("image/jpeg")
public Jpeg getPicture(#PathParam("make") String make, #PathParam("model") PathSegment car, #PathParam("year") String year) {
String carColor = car.getMatrixParameters().getFirst("color");
}
#Pathvariable: This annotation is used to handle template variables in the request URI mapping ,and used them as method parameters.
Ex:
#GetMapping("/{id}")
public ResponseEntity<Patient> getByIdPatient(#PathVariable Integer id) {
Patient obj = service.getById(id);
return new ResponseEntity<Patient>(obj,HttpStatus.OK);
}
I am creating a small validation application using Spring MVC. I am very new to Spring MVC and would like to ensure that what I want is possible.
I have simplified my problem.
I have setup a controller that will be called when a URL is executed. localhost/validate/{SOME TEXT}
The {SOME TEXT} value with be sent to all my validation classes I created.
I currently have 4 classes which does the validation and returns another Object data about what happened during the validation
The 4 validation classes are:
CreditCardValidator
AddressValidator
ZipcodeValidator
AccountNumberValidator
I have a main controller bean that when called I want the string to be passed to each class and the object returned from each to be stored and then finally all results are sent back in a response.
Normally, I would do this without Spring by creating an interface that each validation class implements. Then iteration through the list of classes and execute a method.
The problem doing it that way is that whenever I need to add a new validation class I'll need to register it so the request can use it. This involved modifying existing classes.
Since I am using Spring quick heavily in this application I am wondering if this is possible to do via Spring and annotated classes.
I was thinking of creating a custom annotation that each validation class has and then using spring component-scan to get the classes. This would allow me to create new validations without modifying existing code.
Below is the what I am trying to do.
#Controller
public class StringValidationController {
#RequestMapping(value = "/validate/{text:.+}", method = RequestMethod.GET)
public ModelAndView index(#PathVariable("text") String text) {
ModelAndView model = new ModelAndView();
model.setViewName("index");
model.addObject("result", getListOfValidatedData());
return model;
}
public List getListOfValidatedData(){
//Scan for IValidator annotation
//call each concrete class and pass in text
// get object with has validation information in it
}
}
I have some questions from a design point of view in Spring Web MVC.
Is it good practice to use Request Object in controller? If not, then what is alternative way to pass pass one text fields value to controller? Do I need to create one new from bean for this single fields?
It depends of the situation, in a few cases I used the HttpServletRequest; for example for writing a file to the output stream.
If you want to get the Request Parameters you can use the annotation #RequestParam, that it´s more easy to get the parameters from the request.
Depends that you want to handle, for example for a form you can use #ModelAttribute and this attribute can be in a session or in the request.
For example:
#Controller
public class YourController {
#RequestMapping(value = "someUrl", method = RequestMethod.GET)
public String someMethod(#RequestParam("someProperty") String myProperty)
{
// ... do some stuff
}
}
Check the documentation here:
#RequestParam
#ModelAttribute
#PathVariable
I'm trying to send some data from the client side to the server, and have it processed into a file download.
I'm using a simple HTML form because I want to initialize a file download (and not AJAX).
one of the form fields is an array of items. (the other two are name and description strings).
I'm serializing this field to a string (JSON.stringify) before submitting the form.
on the server side I tried a million techniques (#ModelAttribute vs. #RequestBody, different jackson mapping bean configurations) to either convert this to a single type or to three separate types (String + String + List/Array).
the examples I found were only for AJAX...
can anyone supply a working example or a description of one?
=======
Update:
I've implemented a workaround by JSON.stringify-ing the collection and passing it in one of the inputs,
and on the server side I have:
#RequestMapping(method = RequestMethod.POST, value = "exportSectionsToExcel")
public HttpEntity<byte[]> createExcelWorkBook(#ModelAttribute ExportSectionsListForm exportSectionsListForm) {
Section[] sectionObjects = gson.fromJson(exportSectionsListForm.getSections(), Section[].class);
...
with ExportSectionsListForm object containing strings only:
public class ExportSectionsListForm {
private String name;
private String url;
private String rssUrl;
private String sections;
...
(omitting ctor, getters and setters)
additionally, I found this promising link:
http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/
but didn't try it - seems like I'll need to dynamically generate input elements for this to work, but it might actually be the right solution. has anyone tried this?
The #ModelAttribute tag will try to build the object based on form postings. Since you are serializing your form values to JSON, this wont work. #RequestBody simply gives you a String representing the request body. So, you could get the String representing the JSON being passed in, then demarshal the JSON using Jackson of FlexJSON (or whatever JSON library you use). I am not sure this is the best approach, though.
I would question why you need to serialize the form to JSON to begin with. Spring handles forms with Lists/Maps just fine. Simply submit the form using the #ModelAttribute, making your "array" and List, or whatever you are expecting, on the Controller. So, if I am interpreting your example correctly, my ModelAttribute would look like:
public class ExportSectionsFormBean {
private String name;
private String url;
private String rssUrl;
private List<String> sections;
/* getters/setters */
}
Then my Controller method would look like:
#RequestMapping(method = RequestMethod.POST, value = "exportSectionsToExcel")
public HttpEntity<byte[]> createExcelWorkBook(#ModelAttribute ExportSectionsFormBean exportSectionsFormBean ) {
/* Do whatever with your */
}
On the form side, using the Spring JSTL tags, simply make your "sections" fields look like:
<form:input path="sections[0]" />
<form:input path="sections[1]" />
Or, if you'd rather use HTML, then
<input type="text" name="sections[0]" id="sections0" />
<input type="text" name="sections[1]" id="sections1" />
Which is what gets generated by the above JSTL tags. As long as the values for "sections" is put in the HTTP request as 'section[#]=value', you are all set.
I have been working on the same issue. And if i have several inputs witht eh same name such as:
<input name="somename"/>
<input name="somename"/>
<input name="somename"/>
and i have a form mapped to my method like this:
#ModelAttribute("ReturnsAndExchangesForm") ReturnsAndExchangesForm returnsAndExchangesForm
and in that form i have getters and setters for a property named:
String[] somename , spring is passing those values into that array nicely!