diff --git a/java-realworld/sample/pom.xml b/java-realworld/sample/pom.xml index 206eaca..ca39d21 100644 --- a/java-realworld/sample/pom.xml +++ b/java-realworld/sample/pom.xml @@ -51,6 +51,10 @@ mybatis-spring-boot-starter 3.0.3 + + org.springframework.boot + spring-boot-starter-freemarker + org.springframework.boot diff --git a/java-realworld/sample/src/main/java/com/example/demo/controller/freemakerdemo/FreeMakerDemo.java b/java-realworld/sample/src/main/java/com/example/demo/controller/freemakerdemo/FreeMakerDemo.java new file mode 100644 index 0000000..f10a264 --- /dev/null +++ b/java-realworld/sample/src/main/java/com/example/demo/controller/freemakerdemo/FreeMakerDemo.java @@ -0,0 +1,79 @@ +package com.example.demo.controller.freemakerdemo; + +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import freemarker.template.Configuration; +import freemarker.template.Template; + +import java.io.IOException; +import java.io.PrintWriter; + +@Controller +@RequestMapping("/freemarker") +public class FreeMakerDemo { + @Autowired + private Configuration freemarkerConfig; + + @GetMapping("/template") + public void template(String name, Model model, HttpServletResponse response) throws Exception { + Template tpl = freemarkerConfig.getTemplate("no-return-template.ftl"); + model.addAttribute("name", name); + String templateText = FreeMarkerTemplateUtils.processTemplateIntoString(tpl, model); + response.setContentType("text/html;charset=utf-8"); + PrintWriter writer = response.getWriter(); + writer.write(templateText); + writer.flush(); + writer.close(); + } + + @GetMapping("/welcome") + public String welcome(@RequestParam String name, Model model) { + if (name == null || name.isEmpty()) { + model.addAttribute("name", "Welcome to Safe FreeMarker Demo, try /freemarker/safe/welcome?name=Hacker<>`"); + } else { + model.addAttribute("name", name); + } + return "welcome"; + } + + @GetMapping("/welcome-safe") + public String safeWelcome(@RequestParam String name, Model model) { + if (name == null || name.isEmpty()) { + model.addAttribute("name", "Welcome to Safe FreeMarker Demo, try /freemarker/safe/welcome-safe?name=Hacker<>`"); + return "welcome"; + } else { + model.addAttribute("name", name); + } + return "welcome-safe"; + } + + @GetMapping("/welcome-no-model") + public String welcomeNoModel() { + return "welcome"; + } + + @GetMapping("/welcome-no-ftl") + public String welcomeNoFTL() { + return "welcome-no-existed-totally"; + } + + @ModelAttribute("defaultName") + public String getDefaultName() { + return "default name for FreeMarker Demo"; + } + + @GetMapping("/welcome-default-model") + public String welcomeDefaultModel() { + return "welcome2"; + } + + +} diff --git a/java-realworld/sample/src/main/java/com/example/demo/controller/freemakerdemo/README.md b/java-realworld/sample/src/main/java/com/example/demo/controller/freemakerdemo/README.md new file mode 100644 index 0000000..c100275 --- /dev/null +++ b/java-realworld/sample/src/main/java/com/example/demo/controller/freemakerdemo/README.md @@ -0,0 +1,9 @@ +# Java Freemaker + +使用 Springboot Freemaker Starter 启动后,在 Controller Method 中,返回一个 String 则为 freemaker template 的模版名称(文件名)。 + +找到文件名比较关键。 + +一般作为一个 Controller 来说,他的方法是一个纯 Literal String,例如为 $ret,则需要在数据库中搜索 f`${ret}\.\w+` 类似的文件存在,一般来说这个文件中的 ${...} 是可以供 SSTI 的点。 + +一般的模版注入的审计都类似这种情况,Java 中出现裸 TPL 的渲染和调用的机会不多,框架会包裹一系列的用法。 \ No newline at end of file diff --git a/java-realworld/sample/src/main/resources/application.properties b/java-realworld/sample/src/main/resources/application.properties index 77b558c..e6ebd72 100644 --- a/java-realworld/sample/src/main/resources/application.properties +++ b/java-realworld/sample/src/main/resources/application.properties @@ -5,9 +5,14 @@ spring.datasource.url=jdbc:sqlite:database.db spring.datasource.driver-class-name=org.sqlite.JDBC spring.jpa.database-platform=org.hibernate.dialect.SQLiteDialect +# sqlmap mapper mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.example.demo.model +# freemaker +spring.freemarker.template-loader-path=classpath:/templates/ +spring.freemarker.suffix=.ftl + # auto update spring.jpa.hibernate.ddl-auto=update diff --git a/java-realworld/sample/src/main/resources/templates/no-return-template.ftl b/java-realworld/sample/src/main/resources/templates/no-return-template.ftl new file mode 100644 index 0000000..c9e38b4 --- /dev/null +++ b/java-realworld/sample/src/main/resources/templates/no-return-template.ftl @@ -0,0 +1,9 @@ + + + + Welcome + + +

Welcome ${name}! If you see this, this is loaded by freemarkerConfig, not Controller Method Return

+ + \ No newline at end of file diff --git a/java-realworld/sample/src/main/resources/templates/welcome-safe.ftl b/java-realworld/sample/src/main/resources/templates/welcome-safe.ftl new file mode 100644 index 0000000..b589c47 --- /dev/null +++ b/java-realworld/sample/src/main/resources/templates/welcome-safe.ftl @@ -0,0 +1,9 @@ + + + + Welcome + + +

Welcome ${name?html}!

+ + \ No newline at end of file diff --git a/java-realworld/sample/src/main/resources/templates/welcome.ftl b/java-realworld/sample/src/main/resources/templates/welcome.ftl new file mode 100644 index 0000000..f18907a --- /dev/null +++ b/java-realworld/sample/src/main/resources/templates/welcome.ftl @@ -0,0 +1,9 @@ + + + + Welcome + + +

Welcome ${name}!

+ + \ No newline at end of file diff --git a/java-realworld/sample/src/main/resources/templates/welcome2.ftl b/java-realworld/sample/src/main/resources/templates/welcome2.ftl new file mode 100644 index 0000000..5522eb7 --- /dev/null +++ b/java-realworld/sample/src/main/resources/templates/welcome2.ftl @@ -0,0 +1,9 @@ + + + + Welcome + + +

Welcome ${defaultName}!

+ + \ No newline at end of file