Spring Controller

 Rules to write Controller class

#1. Controller is a class that contains methods which are called as request processing methods.

*) We must add @Controller at class level.

Ex#a: (invalid, missing @Controller)
class Sample {
  @RequestMapping("/show")
  String m1(){}
}
-------------------------------------------------
#2. Every method must be connected with HTTP Method Type (GET/POST) and PATH(URL), then only browser can
    make request and FC will execute. By using annotation @RequestMapping(value="  ",method=RequestMethod.__)

@Controller 
class <ControllerName> {
  //@RequestMapping(value="/path") //default is GET
    @RequestMapping(value="/path",method=RequestMethod.GET)
    public String <methodName>() {
      return "<ViewName>";
    }
    @RequestMapping(value="/path",method=RequestMethod.POST)
    public String <methodName>() {
      return "<ViewName>";
    }
}
*) RequestMethod is a enum.If we do not specify any method type default is GET.

ex#b) (Valid code)
@Controller
class Sample {
  @RequestMapping("/show")
  String m1() {}

  String m2() {} // This is not a request method
                  // FC can not call this method
		  // it is a normal method.
}

#3. URL/Path is case-sensitive. ie /show, /SHOW are different.

  @RequestMapping(value="/show")
  @RequestMapping(value="/Show")  are different

#4. Path can be duplicate with different HTTP Method ie (Combination should not be duplicated)

Ex# (valid)
@Controller
class Sample {

 @RequestMapping("/show") //GET
 String  m1(){}

 @RequestMapping(value="/show",method=RequestMethod.POST) 
 String  m2(){}
 
}
if we add (invalid)
 @RequestMapping(value="/show",method=RequestMethod.GET) 
 String  m3(){}
---------------------------------
#5. We can define a method without path (or) path as '/' at max with one method type(GET/POST)
    ie  @RequestMapping("/") is equals to @RequestMapping

ex: (valid code)
@Controller
class SampleController {
 // @RequestMapping(value="/",method=RequestMethod.GET)
 // @RequestMapping("/")
 // @RequestMapping(method=RequestMethod.GET)
    @RequestMapping      //default / and GET
    String  m1() {}

 // @RequestMapping(value="/",method=RequestMethod.POST)
  @RequestMapping(method=RequestMethod.POST)
  String  m2() {}
}

ex#2 (invalid, duplicate path with same HTTP method)
@Controller
class Process {
  @RequestMapping("/")  //GET
  String m1(){}
  @RequestMapping("/")  //GET
  String m2(){}
}
ex#3 (invalid, duplicate path with same HTTP method)
@Controller
class Process {
  @RequestMapping   //default is / , GET
  String m1(){}
  @RequestMapping("/")  
  String m2(){}
}
====================================
#6 one method can have multiple paths using array input
    @RequestMapping(value={ "/p1","/p2", "/p3" ... })

@Controller
class Sample {
  @RequestMapping(value= { "/home","/login","/logout","/" },method = RequestMethod.GET)
  String m1() {}
}
---------------------------------------------
#7 one method can have multiple Http Methods
    @RequestMapping(
        method = {RequestMethod.GET,RequestMethod.POST}
   )
@Controller
class Sample {
  @RequestMapping(
      value= "/home",
      method= {RequestMethod.GET,RequestMethod.POST}
  )
  String m1() {}
}
*)Note: Step#6 and Step#7 combination also valid.

Q) Can we add two or more @RequestMapping annotation
   for one method?
A) No. it is invalid. We can provide multiple
  paths and methods using one annotation only.

(invalid)
@RequestMapping("/show")
@RequestMapping("/find")
String m1(){}

Q) Can we define one method with one URL/Path get and another URL/PATH with POST?
A) No.
(Invalid)
@GetMapping("/show")
@PostMapping("/test")
String m1() {}
*) but, for both URLs Both method types applied
@RequestMapping(
   value={"/find","/test"},
   method={
        RequestMethod.GET
        RequestMethod.POST
     }
   )
String m1(){}
--------------------------------------------------
Step#8 We can define multiple controller in project in that case recomanded to write Path at class level also.

--Bad Practice--
@Controller
class Employee{
 @RequestMapping("/emp/save")
 String save() {}
 @RequestMapping("/emp/remove")
 String remove() {}
}

@Controller
class Admin {
 @RequestMapping("/admin/save")
 String save() {}
 @RequestMapping("/admin/remove")
 String remove() {}
}
--Good practice: path at class level---
@Controller
@RequestMapping("/emp")
class Employee{
 @RequestMapping("/save")
 String save() {}
 @RequestMapping("/remove")
 String remove() {}
}

@Controller
@RequestMapping("/admin")
class Admin {
 @RequestMapping("/save")
 String save() {}
 @RequestMapping("/remove")
 String remove() {}
}
---------------------------------------------
Step#9 We can write same path at method which exist at class level.

ex: (valid)
@Controller
@RequestMapping("/test")
class Admin {
 @RequestMapping("/test")
 String save() {}
}
URL: http://localhost:8080/test/test
========================================
Q) valid or not?
@Controller
@RequestMapping("/")
class Admin {
 @RequestMapping        /*default is / and GET */
 String fetch() {}
}
A) Valid code.
  http://localhost:8080  (or)
  http://localhost:8080/  (or)
  http://localhost:8080////
========================================
Step#10 we can use new annotations  (Spring 4.x)
(old)
@RequestMapping(value="/path",method=RequestMethod.GET)
(new)
@GetMapping("/path")

(old)
@RequestMapping(value="/path",method=RequestMethod.POST)
(new)
@PostMapping("/path")

=====================================
Q) Which method first execute get or post?
A) No, this is not going to work based on execution order
  Depends on client request. 
  If browser enter URL in address bar with /show then GET
  If same happend with Form Submit (with POST) then POST

Q) Can we use annotation without value attribute?
A) YES, if there are no other attributes exist

 @TestOne({"/a","/b"})  (valid)
 @TestOne(value={"/a","/b"}) (valid)
 @TestOne({"/a","/b"},check=false) (invalid)
 @TestOne(value={"/a","/b"},check=false) (valid)

Q) Difference b/w GET and POST?
A) 
  GET is used to fetch data from server
  POSt is used to send bulk/Form Data to server

  *) If we click hyperlink, enter URL is GET type
  *) Forms supports both GET and POST

Q) Difference b/w @Controller and @RestController?
A)
  Controller is MVC fixed with Java UI(single project)

  RestController to link two projects running in servers
  (BookMyShow ----- PayTM)
  No UI here, Data exchanged using JSON.


Q) Diff b/w @Controller and @ControllerAdvice ?
A) 
  @Controller = Process the request
  @ControllerAdvice = handles the exceptions

*) To create annotations syntax is:
  @interface <name> {  }