How to design a Spring MVC REST service? - java

I want the client and server application to talk to each other using REST services. I have been trying to design this using Spring MVC. I am looking for something like this:
Client does a POST rest service call saveEmployee(employeeDTO, companyDTO)
Server has a similar POST method in its controller saveEmployee(employeeDTO, companyDTO)
Can this be done using Spring MVC?

Yes, this can be done. Here's a simple example (with Spring annotations) of a RESTful Controller:
#Controller
#RequestMapping("/someresource")
public class SomeController
{
#Autowired SomeService someService;
#RequestMapping(value="/{id}", method=RequestMethod.GET)
public String getResource(Model model, #PathVariable Integer id)
{
//get resource via someService and return to view
}
#RequestMapping(method=RequestMethod.POST)
public String saveResource(Model model, SomeResource someREsource)
{
//store resource via someService and return to view
}
#RequestMapping(value="/{id}", method=RequestMethod.PUT)
public String modifyResource(Model model, #PathVariable Integer id, SomeResource someResource)
{
//update resource with given identifier and given data via someService and return to view
}
#RequestMapping(value="/{id}", method=RequestMethod.DELETE)
public String deleteResource(Model model, #PathVariable Integer id)
{
//delete resource with given identifier via someService and return to view
}
}
Note that there are multiple ways of handling the incoming data from http-request (#RequestParam, #RequestBody, automatic mapping of post-parameters to a bean etc.). For longer and probably better explanations and tutorials, try googling for something like 'rest spring mvc' (without quotes).
Usually the clientside (browser) -stuff is done with JavaScript and AJAX, I'm a server-backend programmer and don't know lots about JavaScript, but there are lots of libraries available to help with it, for example see jQuery
See also:
REST in Spring 3 MVC

Yes, Rest is very easy to implement using spring MVC.
#RequestMapping(value="/saveEmploee.do",method = RequestMethod.POST)
#ResponseBody
public void saveEmployee(#RequestBody Class myclass){
//saving class.
//your class should be sent as JSON and will be deserialized by jackson
//bean which should be present in your Spring xml.
}

Related

spring boot application with both front end and restful

I am Planning to build a web application using Spring Boot as restful service.
my spring boot web restful application should be accessible by other application as well. In case if any one accessing the rest service from other application then my application should work as expected.
#Controller
public class GreetingController {
#RequestMapping("/greeting")
public String greeting(#RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
return "greeting";
}
}
In above example if call is made from outside of application then the rest service should return JSON output.
One way we can have some variable to distinguish as request variable. But I do not want like that. Please share some standard way.
Appreciate your help.
Idiomatic way is to rely on Accept request header.
If requester presents Accept: application/json then return him JSON data (REST API).
If requester provides you with Accept: application/xhtml+xml return him HTML (web frontend).
Implementation-wise you should is to be done use #RequestMapping with consumes argument. You need two methods. If business logic for both paths is the same then in could be reused. Business logic should reside in another method or in separate #Service. Business logic on its own should not know, care or rely on transport protocol (HTTP), serialization of request response or presentation. Business logic should just work with POJOs and leave serialization to #Controller.
#Controller
#RequestMapping("/greeting")
public class GreetingController {
#RequestMapping(consumes="application/json")
#ResponseBody //required if you want to return POJO (spring will serialize it to response body)
public void rest() {
//return POJO, it will be serialized to JSON. or serialize pojo
directly and return response with manually set body and headers.
}
#RequestMapping(consumes="application/xhtml+xml")
public void html() {
//populate model, return string pointing to HTML to View
}
}
I suggest creating two controller classes, the second one using #RestController. Then, have two paths; the second could be "rs/greeting". This approach, which separates the Web and RESTful concerns, is much more extensible and doesn't require any weird headers that most clients don't want to deal with.

How to structure spring controllers with functionality shared between web pages

What's a good way to structure spring web controllers when there are different web pages that share functionality?
Let's say there are a Tasks and a Task web page. I can start a task from both pages and I expect that I will remain on the same page when doing so .
What's the best way to do this? Am i forced to duplicate logic as follows:
#Controller
#RequestMapping("/tasks")
public class TasksController {
#GetMapping("/{id}/start")
public String start(#PathVariable String id) {
tasks.start(id);
return "redirect:/tasks.html";
}
}
and
#Controller
#RequestMapping("/task")
public class TaskController {
#GetMapping("/{id}/start")
public String start(#PathVariable String id) {
tasks.start(id);
return "redirect:/task.html";
}
}
ps. I'm not interested in async JavaScipt solutions.
You could use the Regex feature in path variables and get the page name in another variable. So, I would solve this the following way:
#Controller
public class TaskController {
...
#GetMapping({"/{page:tasks?}/{id}/start")
public String start(#PathVariable String page, #PathVariable String id) {
tasks.start(id);
return "redirect:/" + page + ".html";
}
}
If there's more logic or the entry points are quite different extract the common code to a service.
My thought: It is just a matter of how your design and name the controllers. Ideally, I create One controller per business domain object. instead of creating controllers for each page. If we name the Controller and Services for each business domain object, you could avoid this. So i would just have TaskController and call the same URI irrespective of where you call it either from Task page, TaskDetail page or TaskReport page.

Spring Boot #RestController endpoints and Spring Data Rest projections

I'm currently developing a Spring Boot application that exposes endpoints using #RestController and #RequestMapping annotations.
I recently discovered the concept of the projections as defined in Spring Data Rest (#Projection-annotated interfaces and #RepositoryRestResource-annotated JPA repositories) and I'd like to apply this concept to my existing services.
As I understand this post Spring Boot Projection with RestController, (please correct me if I'm wrong), #RestController and #RepositoryRestResource classes both define endpoints. So these annotations seem quite incompatible.
Is there a Spring component which can simply apply the projections concept to the #RestController endpoints ?
Is there a way to manually reroute requests from a endpoint to another ? (for example, using #RestController endpoints as some sort of proxy which performs controls or other operations before rerouting the request to the #RepositoryRestResource endpoints)
EDIT: I add a glimpse of the final code I'd like to have in the end.
#RestController
public class MyController {
#RequestMapping(value = "/elements/{id}", method = RequestMethod.GET)
public ResponseEntity<Element> getElements(
#PathVariable("id") Integer elementId,
#RequestParam("projection") String projection,
#RequestHeader(value = "someHeader") String header{
// [manual controls on the header then call to a service which returns the result]
}
}
#Entity
public class Element {
private Integer id;
private String shortField;
private String longField;
private List<SubElement> subElements;
// [Getters & setters]
}
#Projection(name = "light", types = {Element.class})
interface ElementLight {
public Integer getId();
public String getShortField();
}
If I call /elements/4, I'd get the complete Element having id = 4.
If I call /elements/4?projection=light, I'd get only the id and the short field of the Element having id = 4.
This answer gives some detail about how to create projection instances of your entities - https://stackoverflow.com/a/29386907/5371736
So depending on your projection parameter you could generate the given projections.
Hope this is what you are looking for.

Spring 3.1.0 mvc binding modelattribute along with requestbody

I am new to Spring 3.1.0, and am trying to create an application, which can be exposed as a web application as well as web services.
For a POST where i am submitting a form object using the #ModelAttribute. I also want to expose this method which can consume the same object as XML, through any poster.
Shall i use both #ModelAttribute & #RequestBody together. I have already added the consumes property in the #RequestMapping annotation.
When you submit form, data comes in form-encoded manner, and when you use XML/JSON it comes as a string in body. You'd better place all your common logic to intermediate service layer and call it in your controllers. As a result it allows you to simply build REST services on top of existing HTML pages with forms:
public class Service {
public void registerUser(User user){
}
}
#RequestMapping("users")
public class FormController{
#Autowired private Service service;
#RequestMapping("register")
public ModelAndView registerUser(#ModelAttribute User user){
service.registerUser(user);
}
}
#RequestMapping("service/v1")
public class RESTController{
#Autowired private Service service;
#RequestMapping("users/register")
public ModelAndView registerUser(#RequestBody User user){
service.registerUser(user);
}
}
Actually, you can even put this in one controller.

Spring Mvc Web Application with Rest interface

in my exercise i have to develop a spring application which should be accessible through a WebGUI AND a REST service.
Now i browed through the examples of Spring MVC, there is this hello world tutorial on Spring MVC.
The controller looks like as follows:
#Controller
#RequestMapping("/welcome")
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
model.addAttribute("message", "Spring 3 MVC Hello World");
return "hello";
}
}
Then i looked through the Spring REST example which looks like this:
#Controller
#RequestMapping("/movie")
public class MovieController {
#RequestMapping(value = "/{name}", method = RequestMethod.GET)
public String getMovie(#PathVariable String name, ModelMap model) {
model.addAttribute("movie", name);
return "list";
}
#RequestMapping(value = "/", method = RequestMethod.GET)
public String getDefaultMovie(ModelMap model) {
model.addAttribute("movie", "this is default movie");
return "list";
}
}
Now I am wondering, how do these two examples (Spring-mvc and Spring-rest) differ?
They both use the same annotations and work similar. Aren't that both just REST examples?
How can I provide a Rest-Interface to a Spring-MVC application?
regards
In order to provide rest interface to Spring MVC application, you can apply #RequestMapping annotation with a path name to each of the methods in controller, this creates a unique URL path for each of the rest services you would like to provide.
Meaning, the rest services are nothing but the methods in Spring MVC controller with #RequestMapping annotation.
If you would like to learn how Spring MVC supports Rest Based services, the below link might help:
http://blog.springsource.org/2009/03/08/rest-in-spring-3-mvc/#features
Both samples are about Spring Web MVC.
You should pay more attention to definitions, like what is REST
https://en.wikipedia.org/wiki/Representational_state_transfer
Representational State Transfer is intended to evoke an image of how a
well-designed Web application behaves: presented with a network of Web
pages (a virtual state-machine), the user progresses through an
application by selecting links (state transitions), resulting in the
next page (representing the next state of the application) being
transferred to the user and rendered for their use.
Spring Web MVC greatly facilitates developing REST web APIs and that's it.
Rememeber #ResponseBody as return type on method is going to be REST.
ofcourse returned object can be negotiated with either JSON or XML.

Categories

Resources