TemplateEngine.process抛空指针:工具类抽离后异常,控制器内正常
问题排查:工具类中Thymeleaf TemplateEngine空指针异常原因及解决
问题描述
将HTML渲染逻辑抽离到ProcessHtmlUtil工具类后,调用htmlTemplateEngine.process()时抛出空指针异常,但把相同逻辑直接写在控制器方法内却能正常运行。
核心原因
Spring的依赖注入(如@Autowired)仅对Spring容器管理的Bean生效:
- 你在控制器中手动实例化
ProcessHtmlUtil:ProcessHtmlUtil processHtmlUtil=new ProcessHtmlUtil();,这个实例不在Spring容器的管控范围内,因此Spring不会自动注入htmlTemplateEngine属性,导致它为null,调用方法时触发空指针。 - 控制器本身是Spring管理的Bean(带有
@Controller/@RestController注解),当逻辑写在控制器内时,TemplateEngine会被Spring正常注入,所以无异常。
解决方案
方案1:将ProcessHtmlUtil声明为Spring Bean
- 给
ProcessHtmlUtil添加@Component注解,让Spring容器管理该类:
@Component public class ProcessHtmlUtil { @Autowired TemplateEngine htmlTemplateEngine; public String processHTML(){ try { final Context ctx=new Context(); return htmlTemplateEngine.process("Redoc-Integrate.html",ctx); } catch(RuntimeException e){ log.error("Runtime exception occurred: {}", e.getMessage()); throw e; } catch(Exception e){ log.error("Internal processing error occurred: {}", e.getMessage()); throw new InternalServerException("Internal processing error"); } } }
- 在控制器中通过
@Autowired注入ProcessHtmlUtil,替代手动new:
@RestController public class YourController { @Autowired private ProcessHtmlUtil processHtmlUtil; @GetMapping(value = "/v1/redoc") public ResponseEntity<?> gotoRedocUi(){ HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Content-Type", "text/html; charset=UTF-8"); return new ResponseEntity<>(processHtmlUtil.processHTML(),responseHeaders, HttpStatus.OK); } }
方案2:手动传入TemplateEngine到工具类
如果不想将工具类交给Spring管理,可在调用时主动传入依赖:
- 修改
ProcessHtmlUtil,通过构造方法接收TemplateEngine:
public class ProcessHtmlUtil { private TemplateEngine htmlTemplateEngine; public ProcessHtmlUtil(TemplateEngine htmlTemplateEngine) { this.htmlTemplateEngine = htmlTemplateEngine; } public String processHTML(){ try { final Context ctx=new Context(); return htmlTemplateEngine.process("Redoc-Integrate.html",ctx); } catch(RuntimeException e){ log.error("Runtime exception occurred: {}", e.getMessage()); throw e; } catch(Exception e){ log.error("Internal processing error occurred: {}", e.getMessage()); throw new InternalServerException("Internal processing error"); } } }
- 在控制器中注入
TemplateEngine,并传给工具类实例:
@RestController public class YourController { @Autowired private TemplateEngine htmlTemplateEngine; @GetMapping(value = "/v1/redoc") public ResponseEntity<?> gotoRedocUi(){ ProcessHtmlUtil processHtmlUtil=new ProcessHtmlUtil(htmlTemplateEngine); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Content-Type", "text/html; charset=UTF-8"); return new ResponseEntity<>(processHtmlUtil.processHTML(),responseHeaders, HttpStatus.OK); } }
补充提示
推荐使用方案1,符合Spring依赖注入的设计规范,便于后续代码的扩展和维护。
内容的提问来源于stack exchange,提问作者naruto
相关产品推荐
相关产品推荐

