Receive URL in spring - spring

I try doing confirmation registration from email, on the email I send this code:
String token = UUID.randomUUID().toString(); //for send email
String confirmationUrl = "<a href='" +
"http://localhost:8080/registrationConfirm.html?token="
+ token+"'>Click for end Registration</a>";
helper.setText("message", confirmationUrl.toString());
I receive something like this:
http://localhost:8080/registrationConfirm.html?token=88ab5907-6ab5-40e2-89d5-d6a7e8cea3c2
How I can receive this 88ab5907-6ab5-40e2-89d5-d6a7e8cea3c2 in spring?
I want doing a new controller, he will be check if 88ab5907-6ab5-40e2-89d5-d6a7e8cea3c2 exist in DB, then he activated registration, if no - talk about misstake.
And I do not understand how the conroller will be look, I do so
#RequestMapping(value = "/token", method = RequestMethod.POST)
public #ResponseBody
String getAttr(#PathVariable(value="token") String id,
) {
System.out.println(id);
return id;
}

To complete the comment and hint Ali Dehghani has given (have a look at the answer https://stackoverflow.com/a/17935468/265043):
#RequestMapping(value = "/registrationConfirm", method = RequestMethod.POST)
public #ResponseBody
String getAttr(#RequestParam(value="token") String id) {
System.out.println(id);
return id;
}
Note that I ignored the html suffix in the request mapping annotation. You should read the docs about (default) content negotiation starting at http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-suffix-pattern-match

this another variant
#RequestMapping(value = "/registrationConfirm", method = RequestMethod.POST)
public void getMeThoseParams(HttpServletRequest request){
String goToURL = request.getParameter("token");
System.out.println(goToURL);
}

Related

#PathVariable with slashes in middle of RequestMapping URL

I have a Spring controller mapping like following:
#RequestMapping(value = "api/{pathVar1}/receipt", method = RequestMethod.POST)
#ResponseBody
public String generateReceipt(HttpServletRequest request, #PathVariable String pathVar1) {
....
}
In this case what if the pathVar1 has slash('/').
Example request:
'api/CODE/1/receipt'
pathVar1 is supplied with
'CODE/1'
.
I guess it's not the cleanest solution, but it seems to be working:
Replace #PathVariable in API path with ** to accept anything between "api/" and "/receipt", and then extract the needed part of path.
#RequestMapping(value = "api/**/receipt", method = RequestMethod.POST)
#ResponseBody
public String generateReceipt(HttpServletRequest request) {
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
String apiPath = new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
String neededPathVariableValue = apiPath.substring(0, apiPath.length() - "/receipt".length());
//...
}

Can spring map POST parameters by a way other than #RequestBody

I am using #RestControllers with an application where all requests are POST requests ... As I learned from this post , you can't map individual post parameters to individual method arguments, rather you need to wrap all the parameters in an object and then use this object as a method parameter annotated with #RequestBody thus
#RequestMapping(value="/requestotp",method = RequestMethod.POST)
public String requestOTP( #RequestParam(value="idNumber") String idNumber , #RequestParam(value="applicationId") String applicationId) {
return customerService.requestOTP(idNumber, applicationId);
will not work with a POST request of body {"idNumber":"345","applicationId":"64536"}
MY issue is that I have A LOT of POST requests , each with only one or two parameters, It will be tedious to create all these objects just to receive the requests inside ... so is there any other way similar to the way where get request parameters (URL parameters) are handled ?
Yes there are two ways -
first - the way you are doing just you need to do is append these parameter with url, no need to give them in body.
url will be like - baseurl+/requestotp?idNumber=123&applicationId=123
#RequestMapping(value="/requestotp",method = RequestMethod.POST)
public String requestOTP( #RequestParam(value="idNumber") String idNumber , #RequestParam(value="applicationId") String applicationId) {
return customerService.requestOTP(idNumber, applicationId);
second- you can use map as follows
#RequestMapping(value="/requestotp",method = RequestMethod.POST)
public String requestOTP( #RequestBody Map<String,Object> body) {
return customerService.requestOTP(body.get("idNumber").toString(), body.get("applicationId").toString());
I have change your code please check it
DTO Class
public class DTO1 {
private String idNumber;
private String applicationId;
public String getIdNumber() {
return idNumber;
}
public void setIdNumber(String idNumber) {
this.idNumber = idNumber;
}
public String getApplicationId() {
return applicationId;
}
public void setApplicationId(String applicationId) {
this.applicationId = applicationId;
}
}
Rest Controller Method
#RequestMapping(value="/requestotp",method = RequestMethod.POST)
public String requestOTP( #RequestBody DTO1 dto){
System.out.println(dto.getApplicationId()+" (------) "+dto.getIdNumber());
return "";
}
Request Type -- application/json
{"idNumber":"345","applicationId":"64536"}
OR
#RequestMapping(value="/requestotp",method = RequestMethod.POST)
public String requestOTP( #RequestBody String dto){
System.out.println(dto);
return "";
}

spring can't receive post param send by postman

And My Controller is like
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST,
produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestParam("companyId") Integer companyId) {
return companyManageService.deleteCompany(companyId);
}
But when I type code in chrome console using
$.post( "http://ltc_dev.leapstack.cn/gw/security/auth/company/delete", { companyId: 1 })
.done(function( data ) {
alert( data.success);
alert( data.message);
});
I got correct response, so.....
I'm not sure if it is a postman's bug, or I cofig the controller wrong
In your question, your controller method try to take companyId as request param. In postman you are sending companyId in request body. Like I said in comment you can send request param in url section directly like that: /auth/company/delete?companyId=2. Spring boot can detect companyId request parameter and assign it to method's companyId variable directly.
If you want to send companyId in request body (You said that in comment) you have to change your method's signature like below.
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST, produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestBody Map<String, Integer> map) {
return companyManageService.deleteCompany(map.get("companyId"));
}
Or:
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST, produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestBody CompanyDTO company) {
return companyManageService.deleteCompany(company.getCompanyId);
}
public class CompanyDTO {
private Integer companyId;
//getter setter
}
If you want to use request body and want to catch integer value directly in controller method's variable as integer your request body should be like:
{2}
And controller method should be like:
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST, produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestBody Integer companyId) {
return companyManageService.deleteCompany(companyId);
}

How can i send get method's data to post method without using view?

Suppose, I have a value/data(in my exaple name) in the get method.I want to send and access it in the post method without using view.How can I do that?
#RequestMapping(value="/edit",method = RequestMethod.GET)
public String getPerson(ModelMap model,Person person){
String name="Person Name";
return "personEdit";
}
#RequestMapping(value="/save",method = RequestMethod.POST)
public String savePerson(ModelMap model,Person person){
//I want to access/get **name** here
return "details";
}
you can use modelMap to send the value
#RequestMapping(value="/edit",method = RequestMethod.GET)
public String getPerson(ModelMap model,Person person){
String name="Person Name";
model.addAttribute("name","Person Name");
return "personEdit";
}
you can access your value by using JSTL forexmp : ${name} ..

Mock MVC - Add Request Parameter to test

I am using spring 3.2 mock mvc to test my controller.My code is
#Autowired
private Client client;
#RequestMapping(value = "/user", method = RequestMethod.GET)
public String initUserSearchForm(ModelMap modelMap) {
User user = new User();
modelMap.addAttribute("User", user);
return "user";
}
#RequestMapping(value = "/byName", method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
public
#ResponseBody
String getUserByName(
#RequestParam("firstName") String firstName,
#RequestParam("lastName") String lastName,
#ModelAttribute("userClientObject") UserClient userClient) {
return client.getUserByName(userClient, firstName, lastName);
}
and I wrote following test:
#Test public void testGetUserByName() throws Exception {
String firstName = "Jack";
String lastName = "s";
this.userClientObject = client.createClient();
mockMvc.perform(get("/byName")
.sessionAttr("userClientObject", this.userClientObject)
.param("firstName", firstName)
.param("lastName", lastName)
).andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$[0].id").exists())
.andExpect(jsonPath("$[0].fn").value("Marge"));
}
what i get is
java.lang.AssertionError: Status expected:<200> but was:<400>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.StatusResultMatchers$5.match(StatusResultMatchers.java:546)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:141)
Why this happens? Is it right way to pass the #RequestParam
When i analyzed your code. I have also faced the same problem but my problem is if i give value for both first and last name means it is working fine. but when i give only one value means it says 400. anyway use the .andDo(print()) method to find out the error
public void testGetUserByName() throws Exception {
String firstName = "Jack";
String lastName = "s";
this.userClientObject = client.createClient();
mockMvc.perform(get("/byName")
.sessionAttr("userClientObject", this.userClientObject)
.param("firstName", firstName)
.param("lastName", lastName)
).andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$[0].id").exists())
.andExpect(jsonPath("$[0].fn").value("Marge"));
}
If your problem is org.springframework.web.bind.missingservletrequestparameterexception you have to change your code to
#RequestMapping(value = "/byName", method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
public
#ResponseBody
String getUserByName(
#RequestParam( value="firstName",required = false) String firstName,
#RequestParam(value="lastName",required = false) String lastName,
#ModelAttribute("userClientObject") UserClient userClient)
{
return client.getUserByName(userClient, firstName, lastName);
}
If anyone came to this question looking for ways to add multiple parameters at the same time (my case), you can use .params with a MultivalueMap instead of adding each .param :
LinkedMultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>()
requestParams.add("id", "1");
requestParams.add("name", "john");
requestParams.add("age", "30");
mockMvc.perform(get("my/endpoint").params(requestParams)).andExpect(status().isOk())
#ModelAttribute is a Spring mapping of request parameters to a particular object type. so your parameters might look like userClient.username and userClient.firstName, etc. as MockMvc imitates a request from a browser, you'll need to pass in the parameters that Spring would use from a form to actually build the UserClient object.
(i think of ModelAttribute is kind of helper to construct an object from a bunch of fields that are going to come in from a form, but you may want to do some reading to get a better definition)

Resources