Request Mapping Configuration set globally in spring boot - spring-boot

I have a request mapping in every controller like below, now I want to set this configuration from one place of my applications
Here is my code:
#RestController(value = "AC1004Controller")
#RequestMapping(value = { "api/v1/accounting"},method = RequestMethod.POST ,consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public class AC1004Controller {
}
My target coding is, need to replace the below code from one place of our application
#RequestMapping(value = { "api/v1/accounting"},method = RequestMethod.POST ,consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_FORM_URLENCODED_VALUE})

Generally you map controller's methods with GET, POST, etc ..
so below should be configuration..
Define a property in application.properties
api.endpoint.accounting=/api/v1/accounting
Below controller should mapped with your accounting controller with different-2 methods for post, get to mapped with controller method.
#RestController(value = "AC1004Controller")
#RequestMapping(value = "${api.endpoint.accounting}")
public class AC1004Controller {
#PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<?> addAccount(#RequestBody Account account) {
}
//for get mapping
#GetMapping
public ResponseEntity<?> getAccount() {
}
}

You need to set spring.mvc.servlet.path property in application.properties file.
Like this:
spring.mvc.servlet.path=/AC1004Controller

You just put any of these configurations on application properties file (yaml or properties).
spring.data.rest.basePath=/api
spring.data.rest.base-path=/api

Related

Create generic method to forward to index.html requestes which throws 404

I Spring Boot app combined with Angular 4. I created some routes but when I type into url some string like localhost:8080/items I get error 404 not found. So that's why I created forwarding when it detected if it the url looks like localhost:8080/items it forwards to index.html. But what about a case when I have multiple possible urls to typed and I don't want to rewirte it again and again...?
#RequestMapping(value = "/api/user", method = RequestMethod.POST)
#RequestMapping(value = "/api/user", method = RequestMethod.GET)
#RequestMapping(value = "/api/item", method = RequestMethod.GET)
#RequestMapping(value = "/api/item", method = RequestMethod.POST)
.
.
.
and so on
I wanted to create something generic like:
#Controller
public class ViewController {
#RequestMapping({ "/**" })
public String index() {
return "forward:/index.html";
}
}
but it doesn't work at all. Or there is another way to make it work?
The proper correction of this case is:
In app.module add
{ path: '**', component: ItemListComponent}
which indicated what should you do when something goes wrong and add a specific java controller :
#Controller
public class ViewController {
#RequestMapping(value = "{path:[^\\.]*}")
public String index() {
return "forward:/index.html";
}
}

Map #CookieValue, #RequestHeader etc. to POJO in Spring Controller

I have a bunch of params in my controller and want to map all of them to a separate POJO to keep readability. There is also a #CookieValue, #RequestHeader I need to evaluate and aim for a solution to also map them to that POJO. But how?
I saw a possible solution on a blog but it doesn't work, the variable stays null.
Controller:
#RequestMapping(path = MAPPING_LANGUAGE + "/category", produces = MediaType.TEXT_HTML_VALUE)
#ResponseBody
public String category(CategoryViewResolveModel model) {
doSomething();
}
And my POJO is this:
public class CategoryViewResolveModel {
private String pageLayoutCookieValue;
public CategoryViewResolveModel() {
}
public CategoryViewResolveModel(
#CookieValue(value = "SOME_COOKIE", required = false) String pageLayoutCookieValue) {
this.pageLayoutCookieValue = pageLayoutCookieValue;
}
... some other RequestParams, PathVariables etc.
}
According to the documentation it's not possible for #CookieValue and #RequestHeader.
This annotation is supported for annotated handler methods in Servlet
and Portlet environments.
Take a look at:
https://www.petrikainulainen.net/programming/spring-framework/spring-from-the-trenches-creating-a-custom-handlermethodargumentresolver/
instead of using getParameter to access request parameters you can use getHeader to retrieve the header value and so define your CategoryViewResolveModel just as you were requesting

Different RequestMapping value within same Controller

There is an existing Controller that I want to add an additional get Method with a slightly modified logic. There is the findAll method and I want to add the getMessages method.
#RestController
#RequestMapping(value = "/options", produces = MediaType.APPLICATION_JSON_VALUE)
public class OptionController {
...Definitions etc...
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<?> findAll(#PageableDefault(size = Integer.MAX_VALUE) Pageable pageable) {
Page<Option> page = optionRepository.findAll(pageable);
return ok(pagingAssembler.toResource(page));
}
}
And below the new method:
#RequestMapping(value = "/optionsWelcome", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public ResponseEntity<?> getMessages(#PageableDefault(size = Integer.MAX_VALUE) Pageable pageable) {
Page<Option> page = optionRepository.findAll(pageable);
return ok(pagingAssembler.toResource(page));
}
I am getting 404 for http calls to /optionsWelcome but /options works.
Is it possible to have a controller with mappings for 2 different URLs or do I need to make a second controller?
/options is the mapping for the entire controller. /options/optionsWelcome will probably work.
You need to move /options mapping to the method.

Spring MVC, Controllers design

I am building a web application in Spring MVC with combination of Spring Security. My question regards to inner design of application. To be more specific - how to set up controllers. I got inspired a lot by Pet Clinic example where there is one controller per domain object (Owner controller, Pet controller, Vet Controller and so on).
I would like to introduce an admin backend interface to my application. This would mean to create admin - specific methods and #RequestMappings in each controller. Request mapping paths are secured by intercept-url pattern so I do not have to care where they are. However I find this solution little bit inelegant.
On pet clinics example would it look like:
#Controller
#SessionAttributes(types = Owner.class)
public class OwnerController {
private final ClinicService clinicService;
// Front end method
#RequestMapping(value = "/owners/find", method = RequestMethod.GET)
public String initFindForm(Map<String, Object> model) {
model.put("owner", new Owner());
return "owners/findOwners";
}
// Admin method
#RequestMapping(value = "/admin/owners/find", method = RequestMethod.GET)
public String initFindForm(Map<String, Object> model) {
model.put("owner", new Owner());
//Admin view
return "admin/owners/findOwners";
}
}
Other choice is to have one controller for each #RequestMapping (or per action)
#Controller
#RequestMapping(value = "/admin", method = RequestMethod.GET)
public class AdminController {
private final ClinicService clinicService;
// Admin method
#RequestMapping(value = "/owners/find", method = RequestMethod.GET)
public String initFindForm(Map<String, Object> model) {
model.put("owner", new Owner());
//Admin specific view
return "admin/owners/findOwners";
}
}
This would in my opinion lead to really robust controllers with many methods.
Third option would be to have some kind of mix of those.
#Controller
#SessionAttributes(types = Owner.class)
public class AdminOwnerController {
private final ClinicService clinicService;
// Admin method
#RequestMapping(value = "/admin/owners/find", method = RequestMethod.GET)
public String initFindForm(Map<String, Object> model) {
model.put("owner", new Owner());
//Admin view
return "admin/owners/findOwners";
}
}
My question is what is a standard approach for that?
Usually I use a hybrid approach of AdminOwnerController, in which I end up having approximately 5-10 methods max per Controller.
If you end up having 1-2 methods per controller. I would consider grouping them together based on the admin domain.

Spring REST multiple controllers for one URL but different http methods

I currently have one controller that handles both GET and POST for URL groups:
#Controller
public class RestGroups {
...
#RequestMapping(method = RequestMethod.GET, value = "/groups")
#ResponseBody
public GroupsDto groups() {
return new GroupsDto(getGroups());
}
#RequestMapping(method = RequestMethod.POST, value = "/groups", headers = "Accept=application/xml")
#ResponseBody
public GroupsDto postGroup(#RequestBody GroupDto groupDto) {
groupSaver.save(groupDto.createEntity());
return groups();
}
Now I would like to have TWO controllers, both assigned for same URL but each for different method, something like below:
#Controller
public class GetGroups {
...
#RequestMapping(method = RequestMethod.GET, value = "/groups")
#ResponseBody
public GroupsDto groups() {
return new GroupsDto(getGroups());
}
...
}
#Controller
public class PostGroup {
...
#RequestMapping(method = RequestMethod.POST, value = "/groups", headers = "Accept=application/xml")
#ResponseBody
public GroupsDto postGroup(#RequestBody GroupDto groupDto) {
groupSaver.save(groupDto.createEntity());
return groups();
}
...
}
Is it possible? Because now I get Spring exception that one URL cannot be handled by two different controllers. Is there a workaround for this issue? I really would like to separate those two completely different actions into two separate classes.
This limitation has been solved in Spring 3.1 with its new HandlerMethod abstraction. You'll have to upgrade to 3.1.M2. Let me know if you need an example.

Resources