Контроллер для JSON и HTML с Spring Загрузка

Я пишу приложение, среди прочего, мне нужно делать операции CRUD с определенными объектами. Мне нужно иметь возможность обслуживать как HTML-страницы для пользователей, так и JSON для других приложений. Прямо сейчас мои URL-адреса выглядят так: "Читать":

GET /foo/{id} -> Serves HTML
GET /rest/foo/{id} -> Serves JSON
etc.

Это кажется немного лишним. Я бы предпочел бы что-то вроде этого:

GET /foo/{id}.html OR /foo/{id} -> Serves HTML
GET /foo/{id}.json -> Serves JSON

Может ли Spring Boot сделать это? Если да, то как?

Я знаю, как вернуть JSON:

@RequestMapping(value = "/foo/{id}", method = RequestMethod.GET, produces = "application/json")
public Object fetch(@PathVariable Long id) {
 return ...;
}

Я также знаю, как вернуть HTML:

@RequestMapping("/app/{page}.html")
String index(@PathVariable String page) {
 if(page == null || page.equals(""))
 page = "index";
 return page;
}

Но я не уверен, как сделать контроллер одним или другим на основе запроса.

2 ответа

Это поведение по умолчанию для Spring Boot. Единственное, что вы должны отметить один из @RequestMapping для создания JSON. Пример:

@Controller
class HelloController {
 // call http://<host>/hello.json
 @RequestMapping(value = "/hello", method = RequestMethod.GET, produces = "application/json")
 @ResponseBody
 public MyObject helloRest() {
 return new MyObject("hello world");
 }
 // call http://<host>/hello.html or just http://<host>/hello 
 @RequestMapping(value = "/hello", method = RequestMethod.GET)
 public String helloHtml(Model model) {
 model.addAttribute("myObject", new MyObject("helloWorld"));
 return "myView";
 }
}
</host></host></host>

Подробнее: http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc и http://spring.io/blog/2013/06/03/content-negotiation-using-views


На самом деле, вы смешиваете веб-сервис отдыха с html-страницами, это плохая практика. Если вы хотите построить что-то действительно замечательное, вот мой совет. Напишите только CRUD-операции в ваших контроллерах, и все html/css/js хранятся в некоторой статической папке, и когда вы захотите увидеть часть ui - просто вызовите этот статический файл index.html Вы можете узнать больше об этом здесь - http://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot

Но если вы действительно хотите делать то, что есть сейчас, вот решение:

@RequestMapping(value = "/foo/{id}", method = RequestMethod.GET)
public Object serve(final HttpServletRequest req, final HttpServletResponse resp, @PathVariable final Long id) {
 String header = req.getHeader("Accept");
 // If Accept header will be text/html - then we are forwarding to jsp page.
 if(header.equals("text/html")) {
 req.getRequestDispatcher("login.jsp").forward(req, resp);
 }
 // In other cases we are returning json and setting appropriate headers.
 resp.setHeader("Content-Type", "application/json");
 Object object = "Some string";
 return object;
}

licensed under cc by-sa 3.0 with attribution.