FileNotFoundException при загрузке шаблона freemarker в java
Я получаю исключение, не найденное в файле, при загрузке шаблона freemarker, даже если шаблон действительно присутствует в пути.
Обновление: это работает как веб-сервис. Он вернет xml клиенту на основе поискового запроса. Шаблон загружается успешно, когда я вызываю его из другой java-программы (из статического основного). Но когда клиент запрашивает xml, возникает FileNotFoundException.
ОС: Windows 7
Абсолютный путь файла: C:/Users/Jay/workspace/WebService/templates/
Вот мой код:
private String templatizeQuestion(QuestionResponse qr) throws Exception
{
SimpleHash context = new SimpleHash();
Configuration config = new Configuration();
StringWriter out = new StringWriter();
Template _template = null;
if(condition1)
{
_template = config.getTemplate("/templates/fibplain.xml");
}
else if(condition2)
{
_template = config.getTemplate("/templates/mcq.xml");
}
context.put("questionResponse", qr);
_template.process(context, out);
return out.toString();
}
Полный стек ошибок:
java.io.FileNotFoundException: Template /templates/fibplain.xml not found.
at freemarker.template.Configuration.getTemplate(Configuration.java:495)
at freemarker.template.Configuration.getTemplate(Configuration.java:458)
at com.hm.newAge.services.Curriculum.templatizeQuestion(Curriculum.java:251)
at com.hm.newAge.services.Curriculum.processQuestion(Curriculum.java:228)
at com.hm.newAge.services.Curriculum.processQuestionList(Curriculum.java:210)
at com.hm.newAge.services.Curriculum.getTest(Curriculum.java:122)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:212)
at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:117)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
Ответы
Ответ 1
Пути шаблонов FreeMarker разрешаются объектом TemplateLoader
, который вы должны указать в объекте Configuration
. Путь, который вы указываете как путь к шаблону, интерпретируется TemplateLoader
и обычно относится к некоторому базовому каталогу (даже если он начинается с /
), который по этой причине также называется корневым каталогом шаблонов. В вашем примере вы не указали TemplateLoader
, так что вы используете по умолчанию TemplateLoader
, который существует только для обратной совместимости и почти бесполезен (а также опасен). Итак, сделайте что-нибудь вроде этого:
config.setDirectoryForTemplateLoading(new File(
"C:/Users/Jay/workspace/WebService/templates"));
а затем:
config.getTemplate("fibplain.xml");
Обратите внимание, что префикс /template
теперь отсутствует, поскольку путь к шаблону относительно C:/Users/Jay/workspace/WebService/templates
. (Это также означает, что шаблон не может вернуться из него с помощью ../
-s, что может быть важно для безопасности.)
Вместо загрузки из реального каталога вы также можете загружать шаблоны из SerlvetContext
, из "пути к классу" и т.д. Все зависит от того, какой TemplateLoader
вы выбираете.
Смотрите также: http://freemarker.org/docs/pgui_config_templateloading.html
Обновление: если вы получаете FileNotFoundException
вместо TemplateNotFoundException
, время обновления FreeMarker должно быть не менее 2.3.22. Он также дает лучшие сообщения об ошибках, например, если вы делаете типичную ошибку при использовании значения по умолчанию TemplateLoader
, он сообщает об этом прямо в сообщении об ошибке. Меньше потрачено впустую время разработки.
Ответ 2
Вы можете решить эту проблему таким образом.
public class HelloWorldFreeMarkerStyle {
public static void main(String[] args) {
Configuration configuration = new Configuration();
configuration.setClassForTemplateLoading(HelloWorldFreeMarkerStyle.class, "/");
FileTemplateLoader templateLoader = new FileTemplateLoader(new File("resources"));
configuration.setTemplateLoader(templateLoader);
Template helloTemp= configuration.getTemplate("hello.ftl");
StringWriter writer = new StringWriter();
Map<String,Object> helloMap = new HashMap<String,Object>();
helloMap.put("name","gokhan");
helloTemp.process(helloMap,writer);
System.out.println(writer);
}
}
Ответ 3
Java VM не может найти файл /templates/fibplain.xml
в указанном месте. Это an absolute path
, и весьма вероятно, что вас путают с relative path
. Чтобы получить это исправление, используйте полный (то есть абсолютный) путь, как /home/jaykumar/templates/fibplan.xml($TEMPLATE_HOME/fibplan.xml)
. Другая возможность была бы, если у вас есть такое местоположение как /templates/, возможно, вы не разместили fibplain.xml в этом месте. Для меня только эти два являются наиболее правдоподобными причинами. Я предположил, что это одно из дистрибутивов linux из-за разделителя /
Ответ 4
эта работа как Шарм,
package tech.service.common;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import tech.alphalupi.rhcore.dto.MailResponseDto;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@Service
public class MailingService {
@Autowired
private JavaMailSender sender;
public MailResponseDto sendEmail(String mailTo,String Subject) {
MailResponseDto response = new MailResponseDto();
MimeMessage message = sender.createMimeMessage();
Configuration config = new Configuration(new Version(2, 3, 0));
try {
// set mediaType
MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
TemplateLoader templateLoader = new FileTemplateLoader(new File("src/main/resources/template"));
config.setTemplateLoader(templateLoader);
// add attachment
helper.addAttachment("logo.png", new File("src/main/resources/static/images/spring.png"));
Template t = config.getTemplate("email_template_password.ftl");
Map<String, Object> model = new HashMap<>();
model.put("Name", "ELAMMARI Soufiane");
model.put("location", "Casablanca,Morocco");
String html = FreeMarkerTemplateUtils.processTemplateIntoString(t, model);
helper.setTo("[email protected]");
helper.setText(html, true);
helper.setSubject(Subject);
sender.send(message);
response.setMessage("mail send to : " + mailTo);
response.setStatus(Boolean.TRUE);
} catch (MessagingException | IOException | TemplateException e) {
response.setMessage("Mail Sending failure : "+e.getMessage());
response.setStatus(Boolean.FALSE);
}
return response;
}
}
Ответ 5
На самом деле вы должны указать абсолютный путь (не относительный) для каталога, в который будет помещен шаблон, см. FreeMaker.Конфигурация:
setDirectoryForTemplateLoading(java.io.File dir)
Sets the file system directory from which to load templates.
Note that FreeMarker can load templates from non-file-system sources too. See setTemplateLoader(TemplateLoader) from more details.
Например, вот как получить шаблон из test/resources/freemaker:
private String final PATH = "src/test/resources/freemaker"
//getting singleton of Configuration
configuration.setDirectoryForTemplateLoading(new File(PATH)) //surrounded by try/catch