You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

  1. 给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");
        }
    }
}
  1. 在控制器中通过@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管理,可在调用时主动传入依赖:

  1. 修改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");
        }
    }
}
  1. 在控制器中注入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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:27:47