How to get specific headers (spring-boot application) and pass to controller? - spring-boot

I have a controller in spring boot. I want to get the formId from Form Data (see the image above). #RequestHeader(value="formId") doesn't work. How to get the value?

formId is not from the header but the from form data which is the request body.
You can get it like in this example:
#GetMapping("foo)
public String foo(#RequestBody MultiValueMap<String, String> formData) {
String formId = formData.get("formId");
// your code
}

First you need below dependency,
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1</version>
</dependency>
Then you can get Form data value using below example code,
#PostMapping("/foo")
#ResponseBody
public ResponseEntity<?> getData(#FormParam("formId") String formId) {
System.out.println(formId);
}
In here formParam variable name and parameter name should be equal.

Related

#Pattern not working on controller method with path variable

I have created a controller with an update (PUT) request and applied regex on the id field as shown below but the pattern doesn't get executed and returning back SUCCESS instead of BAD_REQUEST.
#PutMapping("users/{id}")
public Mono<ResponseEntity<UsersApiDTO>> update(#PathVariable #Pattern(regexp = "^[A-Za-z]{1,20}$") String id, #RequestBody #Valid UsersApiDTO usersApiDTO) {
// return response
}
when I pass the wrong 'id' path field value "T001223242345" it is working. It should give me BAD_REQUEST as it works for the request body like if I pass any invalid value for the body parameter it gives BAD_REQUEST.
I have gone through many links and blogs but no luck yet.
You need to add the #Validated annotation onto your RestController in order for path variables to get validated:
#Validated
#RestController
public class YourController {
[...]
I would also suggest reviewing Validating RequestParams and PathVariables in Spring.
Try adding #Validated to your Controller class, and that should work. If it isn't please try to use the latest hibernate validator:
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
</dependency>

Spring boot2 path variable validation

I am using spring boot for creating rest services. I need to validate the parameter passed. I have a service like below,
#GetMapping(value="/employee/{Id}")
public EmployeeDTO getEmployeeDetails(#PathVariable String Id) {
...
}
I need to throw error if Id is not passed in url. Like "Missing Id in request". I was able to achieve using below,
#GetMapping(value={"/employee", "/employee/{Id}"})
public EmployeeDTO getEmployeeDetails(#PathVariable String Id) {
...
}
And handled MissingPathVariableException in ExceptionHandler annotated with #ControllerAdvise.
But I wanted to know is this the right way to check ?
You can use #ControllerAdvise to handle exceptions that are generated while executing your actual code.
For Path variable validation, you can make use of spring-boot-starter-validation.
Add this maven dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Then your controller will look like:
#GetMapping(value={"/employee", "/employee/{Id}"})
public EmployeeDTO getEmployeeDetails(
#NotBlank(message = "Missing Id in request")
#PathVariable String Id) {
...
}
I recommend you to read this: Validating Form Input

Method With #PathVariable In SpringBoot Returns Empty Response

I'm trying to write a method which takes a #PathVariable parameter and redirects user to a jsp file.
#Controller
public class MainController
{
#RequestMapping("/user/{customerId}")
// http://localhost:8080/Test/user/5
public String getCustomerById(#PathVariable("customerId") String customerId, Model model)
{
model.addAttribute("customer_id", customerId);
// this is the user_details.jsp file, I need to show this jsp file to visitor
return "user_details";
}
}
When I try to navigate http://localhost:8080/SpringBlog/user/5 It's showing me an empty response. (Nothing Even In Page Source)
When I looked into Spring output console, it's showing me the following message when I'm trying to navigate :
2017-07-19 13:24:56.191 ERROR 6772 --- [io-8080-exec-75]
o.s.boot.web.support.ErrorPageFilter
Cannot forward to error page for request [/user/5] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
I've already tried following parameter descriptions as the followings :
#PathVariable(value="customerId") String customerId
#PathVariable(name="customerId") String customerId
#PathVariable("customerId") String customerId
#PathVariable String customerId
None of them worked, always empty response with same error message.
I'm sure that all files are in correct place, in my MainController Class
I have several methods with No Parameters, RequestParams, etc.. all of them working as expected. But if I want to create a RequestMapping with #PathVariable, it always returns empty response and same error message in the output console.
But if I try same approach with #RestController it's working as expected:
#RestController
public class RestApi
{
// http://localhost:8080/Test/api/user/56
// Is Working, Returns Hello 56 As Response
#RequestMapping("api/user/{customerId}")
public String apiTest(#PathVariable("customerId") String customerId)
{
return "Hello "+customerId;
}
}
What am I missing ?
Application Details :
<packaging>war</packaging>
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
...
Apache Tomcat/7.0.56
JVM 1.8.0_131-b11
Thanks for your help.
The annotation #RestController automatically adds the #ResponseBody to your methods.
What #ResponseBody does is to bind the outgoing returned value to the HTTP response body using a HttpMessageConverter. If you don't add either the #RestController or #ResponseBody annotation then Spring will try to resolve that to a view, commonly a JSP page.
So in your case Spring is trying to find the view matchin "Hello"+customerId instead of printing out the result of "Hello"+customerId.
So you're using the #PathVariable annotation correctly. :)
You can read more here
Please , check your application.properties file ...
prefix and suffix
spring.mvc.view.prefix: (Where are jsp files) Example /WEB-INF/ or /
spring.mvc.view.suffix: .jsp
If you are using #Controller annotation then you need to add #ResponseBody annotation for binding the outgoing returned value to the HTTP response body. So your code with #Controller should look like:
#Controller
public class MainController
{
#RequestMapping("/user/{customerId}")
#ResponseBody
// http://localhost:8080/Test/user/5
public ModelAndView getCustomerById(#PathVariable("customerId") String customerId, ModelAndView model)
{
model.addAttribute("customer_id", customerId);
// this is the user_details.jsp file, I need to show this jsp file to visitor
model.setViewName("user_details");
return model;
}
}

Why Spring Boot project/REST web-service not response into JSON format?

I have developed 1-REST web services with help of Spring-Boot technology.
Now, while i am going to requesting any thing it isn't responding me into JSON format ? in stead of it it's responding into plain "String" format.
Also, note i have used annotation #RestController at Controller class level.
Some how i am thinking some configuration i am missing. is it so ?
My current Maven Configuration is ,
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
</parent>
Also, i have noticed that while i am requesting(POST) for getting List then in such case it's returns an array of JSON object.
Can anyone guide me what's wrong with me ?
if i understand you right, you want to produce a JSON object in response ?
you have an option in your #RequestMapping that produces a specific format of response.
#RequestMapping(value = "/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
Also you can use a specific format of response to add your object to return, and type of response with ResponseEntity<?>
something similar to this:
public ResponseEntity<?> getAll() {
List<Category> categories = categoryDAO.getAll();
if (!categories.isEmpty()) {
return new ResponseEntity<>(categories, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
EDIT
i add the annotations for #PostMapping it's similar to #RequestMapping
#PostMapping(value = "/list", produces = "application/json; charset=UTF-8")
or also is valid:
#PostMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
i'll leave you a link so you can see what properties had #PostMapping
#PostMapping

how to capture multiple parameters using #RequestParam using spring mvc?

Suppose a hyperlink is clicked and an url is fired with the following parameter list myparam=myValue1&myparam=myValue2&myparam=myValue3 . Now how can I capture all the parameters using #RequestParam in spring mvc?
My requirement is I have to capture all the params and put them in a map.
Please help!
#RequestMapping(value = "users/newuser", method = RequestMethod.POST)
public String saveUser(#RequestParam Map<String,String> requestParams) throws Exception{
String userName=requestParams.get("email");
String password=requestParams.get("password");
//perform DB operations
return "profile";
}
You could use RequestParam in the above mentioned manner.
It seems you can't get
Map<String,String>
because all your params have same name "myparam"
Try this instead:
public ModelAndView method(#RequestParam("myparam") List<String> params) { }
To get all parameters at once try this:
public ModelAndView postResultPage(#RequestParam MultiValueMap<String, String> params)
This feature is described in the #RequestParam java doc (3. Paragraph):
Annotation which indicates that a method parameter should be bound to a web request parameter. Supported for annotated handler methods in Servlet and Portlet environments.
If the method parameter type is Map and a request parameter name is specified, then the request parameter value is converted to a Map assuming an appropriate conversion strategy is available.
If the method parameter is Map<String, String> or MultiValueMap<String, String> and a parameter name is not specified, then the map parameter is populated with all request parameter names and values.
As of Spring 3.0, you can also use MultiValueMap to achieve this:
A rudimentary example would be:
public String someMethod(#RequestParam MultiValueMap<String,String> params) {
final Iterator<Entry<String, List<String>>> it = params.entrySet().iterator();
while(it.hasNext()) {
final String k = it.next().getKey();
final List<String> values = it.next().getValue();
}
return "dummy_response";
}
If anyone is trying to do the same in Spring Boot, use RequestBody in place of RequestParam
Spring mvc can support List<Object>, Set<Object> and Map<Object> param, but without #RequestParam.
Take List<Object> as example, if your object is User.java, and it like this:
public class User {
private String name;
private int age;
// getter and setter
}
And you want pass a param of List<User>, you can use url like this
http://127.0.0.1:8080/list?users[0].name=Alice&users[0].age=26&users[1].name=Bob&users[1].age=16
Remember to encode the url, the url after encoded is like this:
http://127.0.0.1:8080/list?users%5B0%5D.name=Alice&users%5B0%5D.age=26&users%5B1%5D.name=Bob&users%5B1%5D.age=16
Example of List<Object>, Set<Object> and Map<Object> is displayed in my github.
You can use for multiple Params as such
public String saveUser(#RequestParam("email") String userName, #RequestParam("password") String password) throws Exception{
//your code
//perform DB operations
return "profile";
}
For params with same name, you can use MultiValueMap<String ,String>. Then all the values would be present as List
You can use multiple #RequestParam annotations as shown below.
#RequestParam(value="myparam1", required = true) <Datatype> myparam1,
#RequestParam(value = "myparam2", required = false) <Datatype> myparam2,

Resources