001package io.jstach.opt.spring.example.hello; 002 003import java.io.IOException; 004import java.io.Writer; 005 006import org.springframework.beans.factory.annotation.Autowired; 007import org.springframework.http.ResponseEntity; 008import org.springframework.stereotype.Component; 009import org.springframework.stereotype.Controller; 010import org.springframework.web.bind.annotation.GetMapping; 011import org.springframework.web.bind.annotation.ResponseBody; 012import org.springframework.web.servlet.ModelAndView; 013import org.springframework.web.servlet.View; 014 015import io.jstach.jstache.JStacheInterfaces; 016import io.jstach.jstachio.Template; 017import io.jstach.jstachio.TemplateModel; 018import io.jstach.opt.spring.web.JStachioHttpMessageConverter; 019import io.jstach.opt.spring.webmvc.JStachioModelView; 020 021/** 022 * Example hello world controller using different ways to use JStachio for web 023 * development. 024 * 025 * @author agentgt 026 */ 027@Controller 028public class HelloController { 029 030 /** 031 * Placate JDK 18 Javadoc 032 */ 033 public HelloController() { 034 } 035 036 /** 037 * Spring will inject this as the templates are component scanned as this projects 038 * module {@link io.jstach.opt.spring.example/ } has a config that will add @ 039 * {@link Component} to all generated code. 040 */ 041 @Autowired(required = true) 042 public Template<HelloModel> view; 043 044 /** 045 * Here we use JStachio runtime to resolve the renderer (in this case we are calling 046 * them Views) via Springs Http Message Converter. 047 * @apiNote Notice that the method has to be annotated with 048 * <code>@ResponseBody</code>. 049 * @return the model that will be used to find the correct view and then rendered 050 * using that view 051 * @see JStachioHttpMessageConverter 052 */ 053 @GetMapping(value = "/") 054 @ResponseBody 055 public HelloModel hello() { 056 return new HelloModel("Spring Boot is now JStachioed!"); 057 } 058 059 /** 060 * Here we use the generated code directly and return a {@link TemplateModel} which is 061 * analogous to {@link ModelAndView}. 062 * 063 * @apiNote Notice that the method has to be annotated with 064 * <code>@ResponseBody</code>. 065 * @return the template model pair that already has the template found. 066 * @see JStachioHttpMessageConverter 067 */ 068 @GetMapping(value = "/templateModel") 069 @ResponseBody 070 public TemplateModel templateModel() { 071 return HelloModelView.of().model(new HelloModel("Spring Boot is using JStachio TemplateModel!")); 072 } 073 074 /** 075 * Here we use a {@link ResponseEntity} which allows use to set status codes with our 076 * model to be rendered. 077 * @return a response entity. 078 * @see JStachioHttpMessageConverter 079 */ 080 @GetMapping(value = "/responseEntity") 081 public ResponseEntity<HelloModel> entity() { 082 return ResponseEntity.badRequest().body(new HelloModel("Spring Boot is using JStachio ResponseEntity. " 083 + "This is a 400 http error code but is not an actual error!")); 084 } 085 086 /** 087 * Here we could use {@link JStacheInterfaces} to make our model implement 088 * {@link JStachioModelView} to support the traditional servlet MVC approach. The 089 * model will use the static jstachio singleton that will be the spring one. 090 * <p> 091 * This approach has pros and cons. It makes your models slightly coupled to Spring 092 * MVC but allows you to return different views if say you had to redirect on some 093 * inputs ({@link org.springframework.web.servlet.view.RedirectView}). 094 * 095 * @apiNote Notice that the return type is {@link View}. 096 * @return the model and view that will be used as View (see 097 * {@link HelloModelAndView}). 098 * @see JStachioHttpMessageConverter 099 * @see HelloModelAndView 100 */ 101 @SuppressWarnings("exports") 102 @GetMapping(value = "/mvc") 103 public View mvc() { 104 return new HelloModelAndView("Spring Boot MVC is now JStachioed!"); 105 } 106 107 /** 108 * Here we use the {@linkplain #view wired renderer} that does not have filtering and 109 * thus cannot use JMustache for dynamic editing of templates. 110 * @param writer spring will inject the servlet output 111 * @throws IOException an error while writing to the output 112 */ 113 @GetMapping(value = "/wired") 114 public void wired(Writer writer) throws IOException { 115 var model = new HelloModel("JStachioed is wired!"); 116 view.execute(model, writer); 117 } 118 119}