Rest API methods with same URL - spring

I have 2 GET REST methods as given below in a class:
#RequestMapping(value = "test/server", method = {RequestMethod.GET})
public void getServer() {
....
}
#RequestMapping(value = "test/{key}", method = {RequestMethod.GET})
public void getTestPathVariable(#PathVariable("key") final String key) {
....
}
when I consume the rest api with URL "http://localhost:8080/test/server". It always calls the getServer() method.
I am wondering why it does not create an ambiquity as the URL is valid for both getServer() and getTestPathVariable() method. Please help me to understand.

Related

Redirect to URL in Spring MVC (REST API) with params

I have an endpoint in RestController. When request would be processed , there must performed redirecting to another URL and There need to pass one parameters in redirect URL.
#RestController
#RequiredArgsConstructor
#Slf4j
public class RestControllerImpl {
#Value("${uri-root}")
private String uriRoot;
private final Service service;
#PostMapping("/api")
public RedirectView performRequest(#RequestBody Transaction dto) {
service.perform(dto);
String referenceToken = "sldflh#2lhf*shdjkla"
String urlRedirect = uriRoot + "?token=" + referenceToken;
return new RedirectView(urlRedirect);
}
}
The code above doesn't work for me.
I was looking for information on stackoverflow, but it suggests either using ModelAndView or RedirectAttributes attributes. But I need endpoint to accept a Post request that would bring data that will be processed in the service layer.
It is not possible to complete this task. Could someone explain how this can work and how such a task can be accomplished ?
It worked.
#RestController
#RequiredArgsConstructor
#Slf4j
public class RestControllerImpl {
#Value("${uri-root}")
private String uriRoot;
private final Service service;
#PostMapping("/api")
public ResponseEntity createClient(#RequestBody Transaction dto) throws URISyntaxException {
service.perform(dto);
String referenceToken = "sldflh#2lhf*shdjkla"
String urlRedirect = uriRoot + "?token=" + referenceToken;
return ResponseEntity.created(new URI(urlRedirect)).build();
}
}

Spring mvc uri path matching regular expression

I was hoping to match the mapping for /some-slug-1234 in following request mapping but it says no mapping found. What I am doing wrong ?
#Controller
public class MyRequestHandlerController {
#RequestMapping(value = "/[^/]+\\-[0-9]+", method = { RequestMethod.HEAD, RequestMethod.GET } )
public void handleDocument(HttpServletRequest request, HttpServletResponse response){
// render article
}
}

How test Post request with custom object in content type application/x-www-form-urlencoded?

I have controller:
#PostMapping(value = "/value/", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String updateSettings(final Dto dto) {
System.out.println(">>> " + dto);
return "template";
}
Controller works if I send request across chrome window. But when I write test for this method I get problem. Not converted object, value not inserted.
Test:
#Test
#WithMockUser(username = FAKE_VALID_USER, password = FAKE_VALID_PASSWORD)
public void test_B_CreateDtoWithValidForm() throws Exception {
final Dto dto = new Dto();
dto.setId("value");
dto.setEnabled("true");
this.mockMvc.perform(post(URL_SET_PROVIDER_SETTINGS)
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.content(dto.toString()))
.andDo(print());
}
Output is >>> Dto{id=null, enabled=false}
How test Post request with custom object in content type application/x-www-form-urlencoded?
In this case you don't need to use content, but instead you need to use param in this way:
this.mockMvc.perform(post(URL_SET_PROVIDER_SETTINGS)
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("id", "value")
.param("enabled", "true"))
.andDo(print());

How to postForObject list of object?

I have a working example of posting only one object, but i dont know how to post a list of object. Here's how im trying to do this :
Client
protected List<EventStudent> doInBackground(Object... params) {
RestTemplate template = new RestTemplate();
template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
EventStudent[] array = new EventStudent[event.size()];
event.toArray(array);
template.postForObject(URL.GET_EVENT_INFO ,array, EventStudent[].class);
return event;
}
this is how im trying to get them on server:
Server
#RequestMapping(value = "/eventstudent", method = RequestMethod.POST)
#ResponseBody
public List<EventStudent> saveRemider(#RequestBody List<EventStudent>event) {
return service.save(event);
}
But it won't work
the problem is generic and type erasure for List , this would be equivalent of List< ? > in controller method.
Create a custom list class just to wrap List into List that can be handled by spring mvc
public class EventStudentList extends ArrayList<EventStudent> {
}
and use it as
#RequestMapping(value = "/eventstudent", method = RequestMethod.POST)
#ResponseBody
public List<EventStudent> saveRemider(#RequestBody EventStudentList event) {
return service.save(event);
}

rest service not working on jboss 6.0 eap

We have written a service controller for providing rest services in spring which is like---
#Controller
public class ServicesController {
//first service
#ResponseBody
#RequestMapping(value = "/emailDomainValidate", method = RequestMethod.POST, headers = { jsonContentType })
public List<String> emailDomailValidate(#RequestBody EmailDomainValidateVO emailDomainValidate) {
List<String> errorCodes = getEmailDomainValidationService().emailDomainValidation(
emailDomainValidate);
}
//second service
#ResponseBody
#RequestMapping(value = "/changePassword", method = RequestMethod.POST, headers = { jsonContentType })
public List<String> changePassword(#RequestBody ChangePasswordVO changePasswordVO) {
List<String> passwords = getChangePasswordFacade().changePassword(changePasswordVO);
}
}
In web.xml we have provided
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
when we are accessing one of the service by making a rest call----http://"url":8080/service/emailDomainValidate --- this is working
but when we are accessing the other service
http://"url":8080/service/changePassword--- this is not working and is giving us 400 http error code
The steps we have executed so far are ----
deleting the temp directory for the server.
redeployment
change the input class vo for the service which is not working----ChangePasswordVO
please let me why this is still not working when every other service provided is working
Thanks a lot
Try adding a mapping to the controller then add mapping to your methods. This is working for me at least:
#Controller
#RequestMapping('/rest')
public class ServicesController {
private static final Log log = LogFactory.getLog(ExampleRestController.class);
#ResponseBody
#RequestMapping(value = "/emailDomainValidate", method = RequestMethod.POST, headers = { jsonContentType })
public List<String> emailDomailValidate(#RequestBody EmailDomainValidateVO emailDomainValidate) {
if(log.isDebugEnabled()) log.debug('emailDomainValidate hit');
List<String> errorCodes = getEmailDomainValidationService().emailDomainValidation(emailDomainValidate);
}
//second service
#ResponseBody
#RequestMapping(value = "/changePassword", method = RequestMethod.POST, headers = { jsonContentType })
public List<String> changePassword(#RequestBody ChangePasswordVO changePasswordVO) {
if(log.isDebugEnabled()) log.debug('change password hit');
List<String> passwords = getChangePasswordFacade().changePassword(changePasswordVO);
}
}
You then would post to:
http://localhost:8080/service/rest/emailDomainValidate
http://localhost:8080/service/rest/changePassword

Resources