NutzCN Logo
问答 集成freemark时抛空指针了
发布于 2581天前 作者 蛋蛋的忧伤 1888 次浏览 复制 上一个帖子 下一个帖子
标签:

我看这里的步骤进行集成:

https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-views

MainModule:

@Modules(scanPackage = true)
@SetupBy(MySetup.class)
@Encoding(input = "UTF-8", output = "UTF-8")
@IocBy(type = ComboIocProvider.class,
        args = {"*js", "ioc/", "*anno", "com.dd","*org.nutz.plugins.view.freemarker.FreemarkerIocLoader"})
//@Views(DDView.class)
@Views(FreemarkerViewMaker.class)
@Fail("json")
public class MainModule {
}

controller:

@At
    @Ok("fm")
    public Object hello(){
        return new NutMap().setv("hello","world");
    }

报错了:

[WARN ] 14:19:57.594 org.nutz.mvc.impl.processor.FailProcessor.process(FailProcessor.java:28) - Error@/user/hello :
java.lang.NullPointerException
	at org.nutz.plugins.view.freemarker.FreemarkerView.getPath(FreemarkerView.java:98)
	at org.nutz.plugins.view.freemarker.FreemarkerView.render(FreemarkerView.java:56)
	at org.nutz.mvc.impl.processor.ViewProcessor.process(ViewProcessor.java:66)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.MethodInvokeProcessor.process(MethodInvokeProcessor.java:33)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.AdaptorProcessor.process(AdaptorProcessor.java:33)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.ActionFiltersProcessor.process(ActionFiltersProcessor.java:58)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.ModuleProcessor.process(ModuleProcessor.java:123)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.EncodingProcessor.process(EncodingProcessor.java:27)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor.process(UpdateRequestAttributesProcessor.java:15)
	at org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:44)
	at org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:67)
	at org.nutz.mvc.ActionHandler.handle(ActionHandler.java:31)
	at org.nutz.mvc.NutFilter.doFilter(NutFilter.java:202)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1533)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1489)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

报错代码为:


private String getPath(String path) { StringBuffer sb = new StringBuffer(); // 空路径,采用默认规则 if (Strings.isBlank(path)) { sb.append(Mvcs.getServletContext().getRealPath(freeMarkerConfigurer.getPrefix())); sb.append((path.startsWith("/") ? "" : "/")); //这里抛出空指针 sb.append(Files.renameSuffix(path, getExt())); } // 绝对路径 : 以 '/' 开头的路径不增加 '/WEB-INF' else if (path.charAt(0) == '/') { String ext = getExt(); sb.append(path); if (!path.toLowerCase().endsWith(ext)) sb.append(ext); } // 包名形式的路径 else { sb.append(path.replace('.', '/')); sb.append(getExt()); } return sb.toString(); }
11 回复

用的是某个老掉牙的版本??

breemarker 需要指定ftl的路径

@wendal 版本是

<dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.23</version>
    </dependency>


web.xml


<!-- freemarker --> <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> <init-param> <param-name>TemplatePath</param-name> <param-value>/</param-value> </init-param> <init-param> <param-name>template_exception_handler</param-name> <param-value>ignore</param-value> </init-param> <init-param> <param-name>ContentType</param-name> <param-value>text/html</param-value> </init-param> <init-param> <param-name>template_update_delay</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>default_encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>locale</param-name> <param-value>zh_CN </param-value> </init-param> <init-param> <param-name>number_format</param-name> <param-value>0.##########</param-value> </init-param> <init-param> <param-name>datetime_format</param-name> <param-value>yyyy-MM-dd HH:mm</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.ftl</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping>
@Ok("fm:/xxx/index.ftl")

@wendal

 @At
    @Ok("fm:/hello")
    public Object hello(){
        return new NutMap().setv("hello","world");
    }

我webapps下有hello.ftl但是还是找不到这个模板...

[DEBUG] 15:53:26.137 org.nutz.mvc.impl.UrlMappingImpl.get(UrlMappingImpl.java:101) - Found mapping for [GET] path=/user/hello : UserController.hello(UserController.java:340)
[DEBUG] 15:53:26.138 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:151) - Get 'userController'<class com.dd.controller.UserController>
[DEBUG] 15:53:26.138 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:177) - 	 >> Load definition name=userController
[DEBUG] 15:53:26.139 org.nutz.ioc.loader.combo.ComboIocLoader.load(ComboIocLoader.java:161) - Found IocObject(userController) in AnnotationIocLoader(packages=[com.dd])
[DEBUG] 15:53:26.139 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:209) - 	 >> Make...'userController'<class com.dd.controller.UserController>
[DEBUG] 15:53:26.140 org.nutz.ioc.aop.impl.DefaultMirrorFactory.getMirror(DefaultMirrorFactory.java:70) - Load class com.dd.controller.UserController without AOP
[DEBUG] 15:53:26.141 org.nutz.ioc.impl.ScopeContext.save(ScopeContext.java:64) - Save object 'userController' to [app] 
[DEBUG] 15:53:26.161 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:151) - Get 'userDao'<>
[DEBUG] 15:53:26.161 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:151) - Get 'dao'<interface org.nutz.dao.Dao>
[DEBUG] 15:53:26.161 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:151) - Get 'chatMessageDao'<interface com.dd.dao.ChatMessageDao>
[DEBUG] 15:53:26.161 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:177) - 	 >> Load definition name=chatMessageDao
[DEBUG] 15:53:26.161 org.nutz.ioc.loader.combo.ComboIocLoader.load(ComboIocLoader.java:161) - Found IocObject(chatMessageDao) in AnnotationIocLoader(packages=[com.dd])
[DEBUG] 15:53:26.162 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:209) - 	 >> Make...'chatMessageDao'<interface com.dd.dao.ChatMessageDao>
[DEBUG] 15:53:26.162 org.nutz.ioc.aop.impl.DefaultMirrorFactory.getMirror(DefaultMirrorFactory.java:70) - Load class com.dd.dao.impl.ChatMessageDaoImpl without AOP
[DEBUG] 15:53:26.162 org.nutz.ioc.impl.ScopeContext.save(ScopeContext.java:64) - Save object 'chatMessageDao' to [app] 
[DEBUG] 15:53:26.170 org.nutz.ioc.impl.NutIoc.get(NutIoc.java:151) - Get 'dao'<interface org.nutz.dao.Dao>
[DEBUG] 15:53:26.172 freemarker.log._Log4jLoggerFactory$Log4jLogger.debug(_Log4jLoggerFactory.java:45) - Couldn't find template in cache for "hello.ftl"("zh_CN", UTF-8, parsed); will try to load it.
[DEBUG] 15:53:26.173 freemarker.log._Log4jLoggerFactory$Log4jLogger.debug(_Log4jLoggerFactory.java:45) - TemplateLoader.findTemplateSource("hello_zh_CN.ftl"): Not found
[DEBUG] 15:53:26.175 freemarker.log._Log4jLoggerFactory$Log4jLogger.debug(_Log4jLoggerFactory.java:45) - TemplateLoader.findTemplateSource("hello_zh.ftl"): Not found
[DEBUG] 15:53:26.175 freemarker.log._Log4jLoggerFactory$Log4jLogger.debug(_Log4jLoggerFactory.java:45) - TemplateLoader.findTemplateSource("hello.ftl"): Not found
[WARN ] 15:53:26.178 org.nutz.mvc.impl.processor.FailProcessor.process(FailProcessor.java:28) - Error@/user/hello :
java.lang.RuntimeException: freemarker.template.TemplateNotFoundException: Template not found for name "/hello.ftl".
The name was interpreted by this TemplateLoader: FileTemplateLoader(baseDir="E:\Idea_workspace\LuliChat\target\LuliChat-1.0-SNAPSHOT\WEB-INF", canonicalBasePath="E:\Idea_workspace\LuliChat\target\LuliChat-1.0-SNAPSHOT\WEB-INF\").
	at org.nutz.lang.Lang.wrapThrow(Lang.java:184)
	at org.nutz.plugins.view.freemarker.FreemarkerView.render(FreemarkerView.java:80)
	at org.nutz.mvc.impl.processor.ViewProcessor.process(ViewProcessor.java:66)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.MethodInvokeProcessor.process(MethodInvokeProcessor.java:33)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.AdaptorProcessor.process(AdaptorProcessor.java:33)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.ActionFiltersProcessor.process(ActionFiltersProcessor.java:58)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.ModuleProcessor.process(ModuleProcessor.java:123)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.EncodingProcessor.process(EncodingProcessor.java:27)
	at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
	at org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor.process(UpdateRequestAttributesProcessor.java:15)
	at org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:44)
	at org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:67)
	at org.nutz.mvc.ActionHandler.handle(ActionHandler.java:31)
	at org.nutz.mvc.NutFilter.doFilter(NutFilter.java:202)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1533)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1489)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
Caused by: freemarker.template.TemplateNotFoundException: Template not found for name "/hello.ftl".
The name was interpreted by this TemplateLoader: FileTemplateLoader(baseDir="E:\Idea_workspace\LuliChat\target\LuliChat-1.0-SNAPSHOT\WEB-INF", canonicalBasePath="E:\Idea_workspace\LuliChat\target\LuliChat-1.0-SNAPSHOT\WEB-INF\").
	at freemarker.template.Configuration.getTemplate(Configuration.java:1833)
	at freemarker.template.Configuration.getTemplate(Configuration.java:1646)
	at org.nutz.plugins.view.freemarker.FreemarkerView.render(FreemarkerView.java:76)
	... 35 more
04-Dec-2017 15:53:26.633 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory D:\Dev\apache-tomcat-8.0.44\webapps\manager
04-Dec-2017 15:53:26.691 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory D:\Dev\apache-tomcat-8.0.44\webapps\manager has finished in 58 ms

我在WEB-INF下放了个hello.ftl就能找到了.....不是应该user.hello才是WEB-INF下,/user/hello是webapps下嘛.....怎么反了

FreeMarkerViewMaker里面做了自定义吧

package org.nutz.plugins.view.freemarker;

import org.nutz.ioc.Ioc;
import org.nutz.mvc.View;
import org.nutz.mvc.ViewMaker;

public class FreemarkerViewMaker implements ViewMaker {

    protected FreeMarkerConfigurer freeMarkerConfigurer;
    
    protected String iocName = "freeMarkerConfigurer";
    
	public View make(Ioc ioc, String type, String value) {
		if ("fm".equalsIgnoreCase(type) || "ftl".equalsIgnoreCase(type)) {
		    if (freeMarkerConfigurer == null) {
		        for (String name : ioc.getNames()) {
                    if (iocName.equals(name)) {
                        freeMarkerConfigurer = ioc.get(FreeMarkerConfigurer.class);
                        break;
                    }
                }
		        if (freeMarkerConfigurer == null) {
		            freeMarkerConfigurer = new FreeMarkerConfigurer();
		            freeMarkerConfigurer.init();
		        }
		    }
			return new FreemarkerView(freeMarkerConfigurer, value);
		}
		return null;
	}

}

这个类不是我写的呀;......

跟ioc有关吗....

var ioc = {
		conf : {
			type : "org.nutz.ioc.impl.PropertiesProxy",
			fields : {
				paths : [ "config/" ]
			}
		},
		
		siteConf : {
			type : "org.nutz.ioc.impl.PropertiesProxy",
			fields : {
				utf8  : false,
				paths : [ "website.properties" ]
			}
		},
		currentTime : {
			type : "org.nutz.plugins.view.freemarker.directive.CurrentTimeDirective"
		},
		configuration : {
			type : "freemarker.template.Configuration"
		},
		freeMarkerConfigurer : {
			type : "org.nutz.plugins.view.freemarker.FreeMarkerConfigurer",
			events : {
				create : 'init'
			},
			args : [ {
				refer : "configuration"
			}, {
				app : '$servlet'
			}, "WEB-INF", ".ftl", {
				refer : "freemarkerDirectiveFactory"
			} ]
		},
		freemarkerDirectiveFactory : {
			type : "org.nutz.plugins.view.freemarker.FreemarkerDirectiveFactory",
			fields : {
				freemarker : 'org/nutz/plugins/view/freemarker/freemarker.properties',
			}
		}
}

这哥们为何如此之屌,文档可没这么说.....╭(╯^╰)╮ @Rekoe

添加回复
请先登陆
回到顶部