I want to make the method name be the 'value' of #RequestMapping.
That means how to make the code1 be the code2?
//Code1
#RequestMapping("hello")
public Object hello() {
//...
}
//Code2
public Object hello() {
//...
}
-----add more to make it clear ---2019-2-27 15:47:50
TO make it clear, I want to get two API user/hello, user/bye by code:
#RestController
#RequestMapping(value="/user")
public class UserController {
//no requestmapping annotation here, that is what I say 'omitted'
public object hello() {
// your code
}
//no requestmapping annotation here
public object bye() {
// your code
}
```
Suppose you have one common URL in your request.
Let's say you have /user in your all requests then instead of your writing /user in all your method, you can use #RequestMapping(value="/user") as below. You can have multiple methods inside your controller
#RestController
public class UserController {
#RequestMapping(value="/user/hello",method=RequestMethod.yourMethod)
public object hello() { // your code
}
#RequestMapping(value="/user/bye",method=RequestMethod.yourMethod)
public object bye() { // your code
}
Solution:
#RestController
#RequestMapping(value="/user")
public class UserController {
#RequestMapping(value="/hello",method=RequestMethod.yourMethod)
public object hello() { // your code
}
#RequestMapping(value="/bye",method=RequestMethod.yourMethod)
public object bye() { // your code
}
Related
In Jersey we can do something like
#Path("/")
public class TopResource{
#GET
public Response getTop() { ... }
#Path("content")
public ContentResource getContentResource() {
return new ContentResource();
}
}
public class ContentResource {
#GET
public Response getContent() { ... }
}
so,
https://<host> will invoke getTop()
https://<host>/content will invoke getContent()
is there any equivalent in Spring?
I tried
#RestController
#RequestMapping("/")
public class TopResource{
#GetMapping()
public Response getTop() { ... }
#RequestMapping("content")
public ContentResource getContentResource() {
return new ContentResource();
}
}
#RestController
public class ContentResource {
#GetMapping()
public Response getContent() { ... }
}
only top resource works. content would return 404 Not Found.
Not sure how to do this in Spring Boot.
Tried replacing #RestController with #Resource and #Controller for content, but still got 404 Not Found.
There is no option to retun a whole class, please use the Annotation #RequestMapping on top of your content class to split them up.
#RestController
#RequestMapping("/")
public class TopResource{
#GetMapping()
public Response getTop() { ... }
}
#RestController
#RequestMapping("content")
public class ContentResource {
#GetMapping()
public Response getContent() { ... }
}
Im struggling on how to implement a API when the methods in my controller are returning a ModelAndView. Most tutorials I can find are returning ResponseEntities. Should i be making seperate API controllers which strictly handle the API calls under a /api mapping? (which i believe isn't RESTFUL practice). Or is it possible to handle my API calls in the same controller, even when making use of ModelAndView?
My controller looks as following:
#RestController
#RequestMapping("/dish")
public class DishController {
private final DishRepository dishRepository;
public DishController(DishRepository dishRepository) {
this.dishRepository = dishRepository;
}
#GetMapping
public ModelAndView list() {
Iterable<Dish> dishes = this.dishRepository.findAll();
return new ModelAndView("dishes/list", "dishes", dishes);
}
#GetMapping("{id}")
public ModelAndView view(#PathVariable("id") Dish dish) {
return new ModelAndView("dishes/view", "dish", dish);
}
#GetMapping(params = "form")
#PreAuthorize("hasRole('ROLE_ADMIN')")
public String createForm(#ModelAttribute Dish dish) {
return "dishes/form";
}
#ResponseStatus(HttpStatus.CREATED)
#PostMapping
#PreAuthorize("hasRole('ROLE_ADMIN')")
public ModelAndView create(#Valid Dish dish, BindingResult result,
RedirectAttributes redirect) {
if (result.hasErrors()) {
return new ModelAndView("dishes/form", "formErrors", result.getAllErrors());
}
dish = this.dishRepository.save(dish);
redirect.addFlashAttribute("globalMessage", "view.success");
return new ModelAndView("redirect:/d/{dish.id}", "dish.id", dish.getId());
}
#RequestMapping("foo")
public String foo() {
throw new RuntimeException("Expected exception in controller");
}
#ResponseStatus(HttpStatus.OK)
#GetMapping("delete/{id}")
#PreAuthorize("hasRole('ROLE_ADMIN')")
public ModelAndView delete(#PathVariable("id") Long id) {
this.dishRepository.deleteById(id);
Iterable<Dish> dishes = this.dishRepository.findAll();
return new ModelAndView("dishes/list", "dishes", dishes);
}
#ResponseStatus(HttpStatus.OK)
#GetMapping("/modify/{id}")
#PreAuthorize("hasRole('ROLE_ADMIN')")
public ModelAndView modifyForm(#PathVariable("id") Dish dish) {
return new ModelAndView("dishes/form", "dish", dish);
}
You should not use Model and View in RestController. The main goal of RestController is to return data, not views. Take a look here for more details: Returning view from Spring MVC #RestController.
#RestController is a shorthand for writing #Controller and #ResponseBody, which you should only use if all methods are returning an object that should be treated as the response body (eg. JSON).
If you want to combine both REST endpoints and MVC endpoints within the same controller, you can annotate it with #Controller and individually annotate each method with #ResponseBody.
For example:
#Controller // Use #Controller in stead of #RestController
#RequestMapping("/dish")
public class DishController {
#GetMapping("/list")
public ModelAndView list() { /* ... */ }
#GetMapping
#ResponseBody // Use #ResponseBody for REST API methods
public List<Dish> findAll() { /* ... */ }
}
Alternatively, as you've mentioned, you can use multiple controllers:
#Controller
#RequestMapping("/dish")
public class DishViewController { /* ... */ }
#RestController
#RequestMapping("/api/dish")
public class DishAPIController { /* ... */ }
I have Enum Class. I Need to send a Enum class Response from the Spring controller.
I am not able understand how to sent class as Response in spring controller. Please help me for that.
You can add anything which Jackson can de-serialize in a reponse
#RestController
public class HelloController {
#RequestMapping("/monday")
public ResponseEntity<DayOfWeek> monday() {
return new ResponseEntity<DayOfWeek>(DayOfWeek.MONDAY, HttpStatus.OK);
}
#RequestMapping("/days")
public ResponseEntity<List<DayOfWeek>> days() {
return new ResponseEntity<List<DayOfWeek>>(Arrays.asList(DayOfWeek.values()), HttpStatus.OK);
}
}
You can prove this to yourself with the following test, just do the Jacskon de-serialization manually
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class HelloControllerTest {
#Autowired
private MockMvc mvc;
#Test
public void monday() throws Exception {
String json = new ObjectMapper().writeValueAsString(DayOfWeek.MONDAY);
mvc.perform(MockMvcRequestBuilders.get("/monday").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
.andExpect(content().string(equalTo(json)));
}
#Test
public void days() throws Exception {
String json = new ObjectMapper().writeValueAsString(Arrays.asList(DayOfWeek.values()));
mvc.perform(MockMvcRequestBuilders.get("/days").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
.andExpect(content().string(equalTo(json)));
}
}
If you wanna return all enum values than try something like this:
#GetMapping("enum")
public List<MyEnum> paymentMethods() {
return Arrays.asList(MyEnum.values());
}
public enum MyEnum {
FIRST, SECOND, THIRD;
}
My Application class in au.com.domain.demo package and my controller class au.com.domain.demo.control package. I tried to call get method in controller class, but it is not calling.
#SpringBootApplication
public class IssueTrackerApplication {
public static void main(final String[] args) {
System.out.println("coming here.0000..");
SpringApplication.run(IssueTrackerApplication.class, args);
}
}
My controller class is:
#RestController
public class IssueTrackingController {
#RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return "hello";
}
}
I suggest to try to follow an official tutorial from Spring: https://spring.io/guides/gs/rest-service/ - maybe it helps.
The other thing is - try not to return String from the method, but return an object instead. Spring Boot converts POJO classes to JSON.
Hope this helps :)
Trying to map the index controller correctly.
#Controller
#RequestMapping("/")
public class ClientIndexController
{
#RequestMapping(method=RequestMethod.GET)
public ModelAndView index()
{
}
}
or
#Controller
public class ClientIndexController
{
#RequestMapping("/")
public ModelAndView index(HttpServletRequest request)
{
}
}
These both approaches could not distinguish two different requests.
http://domain.com/
http://domain.com/?test=1 - in this case 404 must be thrown.
How can I avoid such behavior?
You can have Map with all request parameters, and check if the map is empty. Then you can implement a lot of different ways in creating a 404 (the one in the example below in only one way (maybe not the best)).
#Controller
#RequestMapping("/")
public class ClientIndexController {
#RequestMapping(method=RequestMethod.GET)
public ModelAndView index(#RequestParam Map<String,String> allRequestParams) {
if(allRequestParams != null && !allRequestParams.isEmpty() {
throw new ResouceNotFoundException();
}
}
#ExceptionHandler(ResouceNotFoundException.class)
#ResponseStatus(404)
public void RprocessValidationError(ResouceNotFoundException ex) {
}
}
If you only want to check that a special parameter is not there then you could use
#RequestMapping(method = RequestMethod.GET, params="!test")
public ModelAndView index(){...}