在java中从json访问嵌套值时遇到了一些困难。 先说说我的做法吧。

首先我将输入作为XML文件然后我将它转换为JSONObject这是我尝试从FTL制作HTML

HTMLMakerDemo

package com.imoveinvest.propertyuploader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.Writer;

import org.json.JSONObject;
import org.json.XML;
import org.springframework.stereotype.Service;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

@Service
public class PDFGenerationDemo implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public static final String RESOURCES_DIR;
    public static final String OUTPUT_DIR;


    static {
        RESOURCES_DIR = "src//main//resources//";
        OUTPUT_DIR = "src//main//resources//output//";
    }

    public void makeHTML() throws IOException, TemplateException {
         String line = "", str = "";
         BufferedReader br = new BufferedReader(new FileReader(RESOURCES_DIR +
         "sample.xml"));
         while ((line = br.readLine()) != null) {
         str += line;
         }
         JSONObject root = XML.toJSONObject(str);
         JSONObject section = (JSONObject)root.get("property-valuation-report");
         section.put("data", section);
         PDFGenerationDemo pdf = new PDFGenerationDemo();
         pdf.makeTemplate(section);
         }
    public void makeTemplate(JSONObject obj) throws TemplateException{
        Configuration cfg = new Configuration();
        cfg.setObjectWrapper(new JSONArrayObjectWrapper());
        cfg.setClassForTemplateLoading(this.getClass(), "/templates/");


        try {
            Template sampleTemplate= cfg.getTemplate("sampleTemplate.ftl");
            Writer consoleWriter = new OutputStreamWriter(System.out);
            sampleTemplate.process(obj, consoleWriter);
            Writer fileWriter = new FileWriter(new File("output.html"));
            sampleTemplate.process(obj, fileWriter);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我的 FTL 是

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <body>
        <h1>Deserialization with Freemarker Hash</h1>
        <#assign obj = data.section>
        <#list obj as item>
            <#if item.name=="valuation">
                <div>${item.capital-value}</div>
            </#if>
        </#list>
    </body>
</html>

为了摆脱JSONparsing错误,我从这个https://stackoverflow.com/a/51876242/12876529

package com.imoveinvest.propertyuploader;

import org.json.JSONArray;
import org.json.JSONException;

import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateSequenceModel;

@SuppressWarnings("deprecation")
public class JSONArrayObjectWrapper extends DefaultObjectWrapper {

    @Override
    public TemplateModel handleUnknownType (Object obj) throws TemplateModelException {

        if (obj instanceof JSONArray) {
            return new JSONArraySequenceModel((JSONArray) obj);
        }

        return super.handleUnknownType(obj);
    }


    public class JSONArraySequenceModel implements TemplateSequenceModel {

        private JSONArray jsonArray;

        public JSONArraySequenceModel(JSONArray jsonArray) {
            this.jsonArray = jsonArray;
        }

        @Override
        public TemplateModel get(int index) throws TemplateModelException {
            TemplateModel model = null;
            try {

                model = wrap(jsonArray.get(index));
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return model;
        }

        @Override
        public int size() throws TemplateModelException {
            return jsonArray.length();
        }

    }


}

所以我的问题是在我的XML文件中我有像capital-value这样的标签

<?xml version="1.0" encoding="utf-8"?>
<sample-data xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:ht="urn:hometrack.com/xslt/extensions">
    <section name="valuation">
        <capital-value>
            <from>855000</from>
            <to>1045000</to>
            <accuracy>medium</accuracy>
            <value>950000</value>
            <valuation-date>2020-02-12T00:00:00</valuation-date>
        </capital-value>
        <last-recorded-sale />
        <rental-value>
            <value>2720</value>
            <yield>3.4357894736842107</yield>
        </rental-value>
        <location>
            <lat>51.611573777232579</lat>
            <long>-0.32247146663868992</long>
        </location>
    </section>
</sample-data>

所以当你看我的 ftl 你会看到我写的

<div>${item.capital-value}</div>

这给了我错误

freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "capital"; see cause exception! The type of the containing value was: extended_hash+string (org.json.JSONObject wrapped into f.e.b.StringModel)

----
FTL stack trace ("~" means nesting-related):
    - Failed at: ${item.capital - value}  [in template "sampleTemplate.ftl" at line 8, column 38]
----
    at freemarker.ext.beans.BeanModel.get(BeanModel.java:186)
    at freemarker.core.Dot._eval(Dot.java:43)
    at freemarker.core.Expression.eval(Expression.java:81)
    at freemarker.core.Expression.evalToNumber(Expression.java:118)
    at freemarker.core.ArithmeticExpression._eval(ArithmeticExpression.java:51)
    at freemarker.core.Expression.eval(Expression.java:81)
    at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:96)
    at freemarker.core.DollarVariable.accept(DollarVariable.java:59)
    at freemarker.core.Environment.visit(Environment.java:326)
    at freemarker.core.Environment.visit(Environment.java:368)
    at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:315)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
    at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:242)
    at freemarker.core.Environment.visitIteratorBlock(Environment.java:595)
    at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:107)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:93)
    at freemarker.core.Environment.visit(Environment.java:326)
    at freemarker.core.Environment.visit(Environment.java:332)
    at freemarker.core.Environment.process(Environment.java:305)
    at freemarker.template.Template.process(Template.java:378)
    at com.imoveinvest.propertyuploader.PDFGenerationDemo.makeTemplate(PDFGenerationDemo.java:57)
    at com.imoveinvest.propertyuploader.PDFGenerationDemo.makeHTML(PDFGenerationDemo.java:46)
    at com.imoveinvest.propertyuploader.controller.SaveOrValidateValuationReport.htmlCall(SaveOrValidateValuationReport.java:152)
    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.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException: null
    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 freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:1487)
    at freemarker.ext.beans.BeanModel.invokeGenericGet(BeanModel.java:268)
    at freemarker.ext.beans.BeanModel.get(BeanModel.java:155)
    ... 64 common frames omitted
Caused by: org.json.JSONException: JSONObject["capital"] not found.
    at org.json.JSONObject.get(JSONObject.java:473)
    ... 71 common frames omitted
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <body>
        <h1>Deserialization with Freemarker Hash</h1>
                        <div>FreeMarker template error (DEBUG mode; use RETHROW in production!):

#1楼 票数:1

您需要对属性名称“capital-value”中的连字符进行转义

仅当您使用 2.3.22 或更高版本的 freemarker 版本时。 请参阅freemarker 变量语法

在这种表达式中,变量名只能包含字母(包括非拉丁字母)、数字(包括非拉丁数字)、下划线(_)、美元($)、at符号(@)。 此外,第一个字符不能是 ASCII 数字 (0-9)。 从 FreeMarker 2.3.22 开始,变量名还可以在任何位置包含减号 (-)、点 (.) 和冒号 (:),但这些必须用前面的反斜杠 () 进行转义,否则会被解释作为运营商。

  ask by Sanjay Sahani translate from so

未解决问题?本站智能推荐:

3回复

如何通过freemarker中的键值访问json值?

有没有办法通过freemarker中的键值访问json值? json 看起来像这样: 我需要这些值才能在方法中使用它们: 我试图用${json.getData()["classPK"]}直接访问它们。 怎么做?
1回复

Freemarker中的JSON数组访问

我想将JSON与freemarker一起使用。 在ajax中,我得到了一个JSON数组。 如何将该数组传递给freemarker并遍历元素? 我知道我应该使用: 但是如何将以下格式的JSON传递到此列表? 编辑:我正在挖掘,它看起来我应该使用jquery来构建HTML。 有更好的
2回复

如何将带有对象和数组索引的字符串转换为json

我从另一个程序Map接收到元素的字符串表示形式: 我需要将其渲染到freemarker-template中。 有问题的 freemarker的平-结构-的-通过参数传递到阵列的对象的- 我们认为不可能在freemarker中解析此类值。 但是freemarker可以评估json。
2回复

FreeMarker模板语言(FTL):将多值XML字段元数据拆分为对相应值进行分组

我有一个人员目录的 XML 元数据,其中一个人可以有多个与其姓名相关的职位、部门和电话号码等。 具有多个值的元数据分别存在于一个字段中(例如字段:职务、部门、电话)。 FTL 似乎以正确的顺序返回记录的数据,即 我想打印这样的数据: 是否有一些 FTL 工具可以将具有多个值的字段放在一个数组或其他
3回复

如何在FTL文件中读取JSONArray?

我的Java文件中硬编码了以下JSON对象 杰森的形成为: 您能告诉我如何在FTL文件中读取Json数组吗? FTL文件: 错误:
2回复

如何将Control-Parm中的工作流属性传递给Alfresco中的FTL文件?

因此,对于我的项目,我们在Alfresco存储库中有一些javascript代码作为规则运行。 因此,只要新文档进入某个空间,就会动态创建一个新文件夹,并将该文档移动到新创建的空间中。 此外,无论何时创建新文件夹,都会对文档更新属性(期望caseID实际上是基于数据库中序列的动态生成的值):
1回复

FreeMarker模板JSON-给它一个节点?nextSibling找出当前节点是否有兄弟节点?

我想将 XML 文件转换为 JSON。 问题是,我有结构 我想要它的 JSON 格式,如: 但是最后一个孩子之后总是有一个逗号“,”。 使用 freemarker,有一种方法可以确定节点是否有父节点、子节点或其他节点,例如节点?父节点、节点?子节点。 但是没有机会发现它是否有兄弟姐妹。 freem
1回复

如何使用Java编辑,处理和保存FTL文件?

我有一个代码可以解析XML文件,对其进行编辑并保存(为此使用dom)。 现在,我有一些扩展名为.ftl的文件。 我已经设法用给定的答案( 使用freemarker模板配置 )处理了ftl文件,但是,我无法将编辑后的xml保存为FTL。 所有这些都是用Java编写的。 关于如何实现问题的