Как реализовать REST API на RestController с использованием ModelAndView - PullRequest
0 голосов
/ 07 июня 2019

Я изо всех сил пытаюсь реализовать API, когда методы в моем контроллере возвращают ModelAndView. Большинство учебных пособий, которые я могу найти, возвращают ResponseEntities. Должен ли я делать отдельные контроллеры API, которые строго обрабатывают вызовы API в соответствии с / api-отображением? (Который я верю, не является ОТДЫХНОЙ практикой). Или можно обрабатывать мои вызовы API в одном контроллере, даже когда используется ModelAndView?

Мой контроллер выглядит следующим образом:

@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);
    }

Ответы [ 2 ]

1 голос
/ 07 июня 2019

@RestController - это сокращение для записи @Controller и @ResponseBody, которое следует использовать, только если все методы возвращают объект, который должен рассматриваться как тело ответа (например, JSON).

Если вы хотите объединить как конечные точки REST, так и конечные точки MVC в одном контроллере, вы можете аннотировать его с помощью @Controller и индивидуально аннотировать каждый метод с помощью @ResponseBody.

Например:

@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() { /* ... */ }
}

В качестве альтернативы, как вы упомянули, вы можете использовать несколько контроллеров:

@Controller
@RequestMapping("/dish")
public class DishViewController { /* ... */ }

@RestController
@RequestMapping("/api/dish")
public class DishAPIController { /* ... */ }
1 голос
/ 07 июня 2019

Вы не должны использовать модель и вид в RestController. Основная цель RestController - возвращать данные, а не представления. Посмотрите здесь для получения более подробной информации: Возвращение представления из Spring MVC @ RestController .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...