org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template
最近再做一个开源项目的时候,用到了thymeleaf作为模板引擎,自动生成页面的时候,一直在报错,下面贴出错误提示代码exceptionorg.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.Templat
最近再做一个开源项目的时候,用到了thymeleaf作为模板引擎,自动生成页面的时候,一直在报错,下面贴出错误提示代码
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "ServletContext resource [/WEB-INF/templates/item/createPage.html]")
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "ServletContext resource [/WEB-INF/templates/item/createPage.html]")
org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:235)
org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:649)
org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause
java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/templates/item/createPage.html]
org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:159)
org.thymeleaf.spring5.templateresource.SpringResourceTemplateResource.reader(SpringResourceTemplateResource.java:103)
org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:223)
org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:649)
org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
对应的controller为:
@Controller
@RequestMapping("/item")
public class ItemController {
@Value("${pagePath}")
private String pagePath;
@Reference
private SpuService spuService;
@Autowired
private TemplateEngine engine;
@Reference
private CategoryService categoryService;
/**
* 通过获取spuId来创建页面
* @param id
*/
@GetMapping("/createPage")
public void createPage(String id){
Goods goods=spuService.findGoodsById(id);
Spu spu = goods.getSpu();
List<Sku> skuList = goods.getSkuList();
List<String> categories=new ArrayList<>();
categories.add( categoryService.findById(spu.getCategory1Id()).getName() );//一级分类
categories.add( categoryService.findById(spu.getCategory2Id()).getName() );//二级分类
categories.add( categoryService.findById(spu.getCategory3Id()).getName() );//三级分类
//sku页面url集合 以sku的spec的json数据为键值 skuId为url
//sku地址列表
Map<String,String> urlMap=new HashMap<>();
for(Sku sku:skuList){
if("1".equals(sku.getStatus())){
String specJson = JSON.toJSONString( JSON.parseObject(sku.getSpec()), SerializerFeature.MapSortField);
urlMap.put(specJson,sku.getId()+".html");
}
}
//System.out.println("urls = " + urls);
// //System.out.println("goods = " + goods);
//每个sku生成一个一个页面
for(Sku sku:skuList){
//(1) 创建上下文和数据模型
Context context=new Context();
Map<String,Object> dataModel= new HashMap<>();
dataModel.put("spu",spu);
dataModel.put("sku",sku);
dataModel.put("categoryList",categories);
dataModel.put("skuImages", sku.getImages().split(",") );//sku图片列表
dataModel.put("spuImages", spu.getImages().split(",") );//spu图片列表
Map paraItems= JSON.parseObject( spu.getParaItems());//参数列表
dataModel.put("paraItems",paraItems);
Map<String,String> specItems = (Map)JSON.parseObject(sku.getSpec());//规格列表 当前sku
dataModel.put("specItems",specItems);
//{"颜色":["天空之境","珠光贝母"],"内存":["8GB+64GB","8GB+128GB","8GB+256GB"]}
//{"颜色":[{ 'option':'天空之境',checked:true },{ 'option':'珠光贝母',checked:false }],.....}
Map<String,List> specMap = (Map)JSON.parseObject(spu.getSpecItems());//规格和规格选项
for(String key :specMap.keySet() ){ //循环规格
List<String> list = specMap.get(key);//["天空之境","珠光贝母"]
List<Map> mapList=new ArrayList<>();//新的集合 //[{ 'option':'天空之境',checked:true },{ 'option':'珠光贝母',checked:false }]
//循环规格选项
for(String value:list){
Map map=new HashMap();
map.put("option",value);//规格选项
if(specItems.get(key).equals(value) ){ // 如果和当前sku的规格相同,就是选中
map.put("checked",true);//是否选中
}else{
map.put("checked",false);//是否选中
}
Map<String,String> spec= (Map)JSON.parseObject(sku.getSpec()) ;//当前的Sku
spec.put(key,value);
String specJson = JSON.toJSONString(spec , SerializerFeature.MapSortField);
map.put("url",urlMap.get(specJson));
mapList.add(map);
}
specMap.put(key,mapList);//用新的集合替换原有的集合
}
dataModel.put("specMap" ,specMap);
context.setVariables(dataModel);
//(2)准备文件
File dir =new File(pagePath);
if( !dir.exists()){
dir.mkdirs();
}
File dest= new File(dir, sku.getId()+".html" );
//(3)生成页面
try {
PrintWriter writer=new PrintWriter( dest,"UTF-8");
engine.process("item",context,writer );
System.out.println("生成页面:"+sku.getId()+".html");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
即根据查到的spuID,和相应的模板,来动态的生成页面
下面分析报错
他说我
template: "ServletContext resource [/WEB-INF/templates/item/createPage.html]"
我很好奇,我tm就没有返回什么createPage啊,怎么会突然蹦出来这个玩意,这是我controller中的方法啊,奇了怪了
再往下看。root cause1可以看出是thymeleaf模板引擎那里出了问题,再往下就是io那里出了问题,但是奇怪的是,我想要生成的页面都已经生成了
报错是在生成之后报错的,这个时候我感觉确实是在完成了之后返回了某些东西,导致在哪里出错了,后来找到了一些内容:
解决方案1
发现人家说了一个问题,注解的问题,才想到,确实是这样,
通过将注解:@Controller改成@RestController,完美解决
同时有另外一个问题:
有时候只可以用Controller
@RestController和@Controller的区别
@RestController注解相当于@ResponseBody + @Controller合在一起的作用。
如果使用@RestController注解,则Controller类中的方法无法返回jsp页面,配置的视图解析器InternalResourceViewResolver则不起作用,返回的内容就是Return 里的内容(String/JSON)。
@Controller标识一个Spring类是Spring MVC controller处理器
在@controller注解中,返回的是字符串,或者是字符串匹配的模板名称,通过视图解析器InternalResourceViewResolver直接渲染视图,与html/jsp页面配合使用的
回去复习springmvc了,复习好了再回来继续补充~~~~~
更多推荐
所有评论(0)