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