0

I am learning spring boot, and i developed the below simple example. I would like to annotate a class as Controller using @Controller. this class has constructor and I want to have access to GreetingFromDeuController as shown:

http://localhost:8080:/GreetingFromDeuController?str = "hi"

the error i am receiving is

@RequestMapping is not applicable on a constructor

please let me know how to solve.

code:

@Controller
@RequestMapping("/GreetingFromDeuController")
public class GreetingFromDeuController {

private String str;

@RequestMapping("/GreetingFrom/deu")
GreetingFromDeuController(@RequestParam(value = "str") String str) {
    this.str = str;
}

@RequestMapping("/GreetingFromDeuController")
public String getGreetingFromDeu() {
    return this.str;
}   
}
Amrmsmb
  • 1
  • 27
  • 104
  • 226

4 Answers4

1

First of all your constructor gets initialize much before you hit your URL. So you need to work on your design or tell me your business requirement and I will try to provide you a solution. My refactor code solution will help you to achieve that in two steps. First hit POST method which will do work on setting variable and then subsequent hits of GET method will return that set value.

We can refactor code like below. It will explain use of RequestMapping on method and class.

Considering we have to write two API, one for reading and one for writing.

URLS :

1. POST http://localhost:8080/example/greetings (in request body send {str:'hi'})
2. GET  http://localhost:8080/example/greetings

 @Controller
 @RequestMapping("/example")
 public class GreetingFromDeuController {

  private String str;

  @RequestMapping(value="/greetings" , method = RequestMethod.POST)
  public void setGreetingFromDeu(@RequestBody(value = "str") String str) 
  {
    this.str = str;
  }

  @RequestMapping(value="/greetings" , method = RequestMethod.GET)
  public String getGreetingFromDeu() 
  {
   return this.str;
  }   
}
Tejas
  • 276
  • 2
  • 8
  • Yes. You can autowire str variable. There is no restriction on it. Just make sure in context before loading this class, compatible string bean is available which Spring can attach to str. – Tejas Jul 28 '19 at 08:42
0

As far I am concerned, @RequestMapping is not meant for constructors. It should be used for annotating methods or classes. Methods that are responsible for handling requests.

Dio
  • 1
  • 2
  • but as shown in the code posted, the method is just a getter, but i need the constructor to initialize it.please how can i do that – Amrmsmb Jul 13 '19 at 14:14
0

The @RequestMapping documentation says:

Annotation for mapping web requests onto methods in request-handling classes with flexible method signatures.

Then you can not do that, if you want to initialize your variables or whatever you can use several ways:

1.- Use @PostConstruct

@PostContruct
public void init() {
   this.str = "Anything";
}

2.- Use a simple request to set anything only

@RequestMapping(value="/refresh/anythings", method = RequestMethod.PUT)
public void refresh(@RequestBody(value = "str") String str) {
    this.str = str;
}   

3.- Use @Value

In application.properties / application.yaml

properties.str = anything    

In the Controller

@Value("${properties.str:default}") // by default str is "default"
public String str;

@RequestMapping(value="/greetings" , method = RequestMethod.GET)
public String getGreetingFromDeu() {
    return this.str;
}       
Jonathan JOhx
  • 5,784
  • 2
  • 17
  • 33
  • thx, in point number 2, the method returns a Strign however the body doesnot contains return statement..should it return void or string – Amrmsmb Jul 13 '19 at 15:43
0

@RequestMapping should be used to map request with endPoint. which can be used as class level and method level.

You can use @RestController (improved from @Controller see difference).

The ideal flow for Spring Boot is Controller -> Service -> Repository

Controller -> maps request with endPoint and return response
Service -> perform business logic
Repository -> Handle database operation

Example

@RestController
    @RequestMapping("/api")
    public class GreetingController {

    @Autowired GreetinService greetingService;

    // Request http://localhost:8080/api/GreetingFrom
    @GetMapping("/GreetingFrom")
    public ResponseEntity<String> GreetingRequestParam(@RequestParam(value = "name") String name) {
        greetingService.performBusinessLogic(name);
        return new ResponseEntity<String>("Greetings from "+name,HttpStatus.OK);
    }

    // Request http://localhost:8080/api/GreetingFrom/user2121
    @GetMapping("/GreetingFrom/{name}")
    public ResponseEntity<String> GreetingPathVariable(@PathVariable(value = "name") String name) {
        return new ResponseEntity<String>("Greetings from "+name,HttpStatus.OK);
    }
}
Romil Patel
  • 12,879
  • 7
  • 47
  • 76