Я также использую шаблон контроллера-службы-репозитория в нескольких проектах, и вот как я его выкладываю:
@RestController // 1
@RequestMapping(value = "/users") // 2
public class UserController {
private final UserService userService;
@Autowired // 3
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(value = "/{user_id}", method = RequestMethod.GET) //4
@ResponseStatus(HttpStatus.OK) //5
public UserModel getUser(@PathVariable(value="user_id") long user_id) { //6
return userService.getUserById(user_id);
}
@RequestMapping(method = RequestMethod.POST) // 7
@ResponseStatus(HttpStatus.CREATED) // 8
public UserModel getUser(@ResponseBody UserModel userModel) { // 9
return userService.createUser(usermodel);
}
}
1) @RestController представляет собой комбинацию @Controller и @ResponseBody, что по существу означает, что каждый метод в вашем классе будет иметь тело ответа.
2) Префикс @RequestMapping значения в этом классе с / users
3) Autowiring в Constructor является самым безопасным подходом к инъекции bean-компонентов.
4) Этот метод будет доступен через запрос GET для / users / {user_id}
5) Этот метод вернет код состояния HttpStatus.OK при успешном завершении (200)
6) Извлекает переменную пути «user_id» из запроса. Используйте тот же числовой тип, что и ваш идентификатор пользователя (т.е. int или long).
7) Этот метод будет доступен через запрос POST для / users
8) Этот метод будет return HttpStatus.CREATED код состояния при успехе (201)
9) Извлекает UserModel из тела запроса (должен иметь ту же структуру, что и json, указанный ниже).
Нет реальных отличий от Cepr0 и моего подхода, это чисто предпочтение стиля.
UserModel может быть классом следующим образом:
public class UserModel {
private String username;
// Constructor, Getter, Setter...
}
И это вернет объект JSON в тело ответа следующим образом:
{
"username":"username"
}
Если вы хотите обрабатывать Исключения в своем контроллере (и даже управлять данные, возвращаемые исключением, вы можете использовать @ExceptionHandler следующим образом:
@ExceptionHandler(Exception.class)
public ResponseEntity handleGenericException(Exception ex){
return ResponseEntity
.status(HttpStatus.I_AM_A_TEAPOT)
.body(new CustomExceptionWrapper(ex)));
}
Где CustomExceptionHandler преобразует исключения, созданные вашим приложением, в формат, который вы решите (это также может быть POJO, а Spring Boot преобразует его в JSON для вас!) [/ g17]
Чтобы более точно ответить на ваши вопросы: 1) Вы должны выбросить исключение, если пользователь не будет найден, который будет включать в себя статус ответа 404 (NOT FOUND). Возвращение null - это, как правило, плохая идея, поскольку это может означать много чего.
1.1?) Если ваш пользователь отправляет недопустимую строку, вы можете посмотреть, какое исключение оно вызывает на вашем сервере, и использовать обработчик исключений, чтобы справиться с ним и вернуть соответствующий ответ (возможно, BAD_REQUEST?)
2) Да, используйте long, если ваши идентификаторы использования длинны.
Проверьте сайт baeldung , действительно рекомендуют их для изучения Spring Boot.
На этот вопрос нет единого ответа, но если вы посмотрите на такие приложения, как Codename One Build , вы заметите, что они адаптируются к этому форм-фактору.
Обычно мы просто используем isTablet()
для адаптации пользовательского интерфейса в ключевых точках к другому форм-фактору. Одним из элементов является постоянное боковое меню , которое мы включаем в методе init с помощью кода, подобного следующему:
if(Display.getInstance().isTablet()) {
Toolbar.setPermanentSideMenu(true);
}
Это позволяет боковому меню оставаться открытым все время. В коде мы пытаемся использовать Container
вместо Form
. Это позволяет нам упаковать несколько логических элементов в единый интерфейс для режима планшета.