当我控制器中的方法返回ModelAndView时,我正在努力实现API。我可以找到的大多数教程都在返回ResponseEntities。我应该制作单独的API控制器来严格处理/ api映射下的API调用吗? (我认为这不是RESTFUL的实践)。还是即使在使用ModelAndView时也可以在同一控制器中处理我的API调用?
我的控制器如下:
@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);
}
答案 0 :(得分:1)
您不应在RestController中使用模型和视图。 RestController的主要目标是返回数据,而不是视图。在这里查看更多详细信息:Returning view from Spring MVC @RestController。
答案 1 :(得分:1)
Internal Server Error: /parts/10/
Traceback (most recent call last):
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: part_management_part.class_code_id, part_management_part.number
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 116, in view
return self.dispatch(request, *args, **kwargs)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 84, in partial_update
return self.update(request, *args, **kwargs)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 70, in update
self.perform_update(serializer)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 80, in perform_update
serializer.save()
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 209, in save
self.instance = self.update(self.instance, validated_data)
File "/home/anani/PycharmProjects/part_management_backend/part_management/serializers.py", line 55, in update
instance.save()
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 741, in save
force_update=force_update, update_fields=update_fields)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 779, in save_base
force_update, using, update_fields,
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 851, in _save_table
forced_update)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 900, in _do_update
return filtered._update(values) > 0
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/query.py", line 760, in _update
return query.get_compiler(self.db).execute_sql(CURSOR)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1429, in execute_sql
cursor = super().execute_sql(result_type)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1100, in execute_sql
cursor.execute(sql, params)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 99, in execute
return super().execute(sql, params)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: part_management_part.class_code_id, part_management_part.number
[06/Jun/2019 23:37:04] "PATCH /parts/10/ HTTP/1.1" 500 22340
是编写@RestController
和@Controller
的简写,只有在所有方法都返回一个应被视为响应主体的对象(例如JSON)时,才应使用它
如果要在同一控制器中同时合并REST端点和MVC端点,则可以使用@ResponseBody
对其进行注释,并使用@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() { /* ... */ }
}