【问题标题】:How do I convert JSON to Obj for InputText如何为 InputText 将 JSON 转换为 Obj
【发布时间】:2020-04-30 17:27:39
【问题描述】:

我有 json List<String> 的列表,每个字符串都有这样的 json {"id":"22","name":"Name","order":"1"} 我想将它提取到输入框列表然后当我保存它时 我想接受所有更改并将它们转换为 JSON

@ManagedBean
@ViewScoped
public class LiveStreamController extends ProductController implements Serializable {

    private static final long serialVersionUID = 5037909267669512508L;
    private static final Logger LOGGER = LoggerFactory.getLogger(LiveStreamController.class);

    private LiveStream liveStream;

....
}

 public class LiveStream extends Product implements Serializable {
    private List<String> jsons = new ArrayList<>();
...
}

我想读它

            <c:forEach items="#{liveStreamController.liveStream.jsons}"
                var="json ">
                <h:outputFormat value="#{json.name}" />
                <p:inputText value="#{json.order}" />
            </c:forEach>

【问题讨论】:

  • 这能回答你的问题吗? Decoding JSON String in Java
  • 你需要 json 简单的库。见@AlexisPhilip 的评论
  • 在托管 bean 中如何处理?
  • 这能回答你的问题吗? How to parse JSON in Java
  • 尽管“这是否回答了您的问题”参考资料都在告诉您需要什么(尽管如果您在大多数投票中订购答案,则链接未参考当前存在的标准),我创建了一个答案,说明您最初的想法为何行不通,以及为什么需要转换为更强类型的对象。

标签: java jsf


【解决方案1】:

实际上,您不是在问 JSF 问题,而是问 EL 问题,因为#{json.name} 表达式就是...Expression Language

关于“问题”...

如果var="json" 的值是String,在您的情况下,它将由肯定知道String 的基本解析器解析。将尝试通过显然不存在的getName() 调用字符串上的属性name,从而导致Property 'name' not found on type java.lang.String。所有这些也在Property 'someproperty' not found on type java.lang.String 中进行了解释。因此,像在您的示例中那样使用它是行不通的

关于阅读的解决方案...

读取 JSON 并显示它基本上有 3 种解决方案

新的字符串 EL 解析器
您可以创建一个自定义 EL 解析器并将其按解析器的顺序放在首位,以便对于需要解析的 每个字符串 检查它是否有效地为 JSON(最少解析它)以及您是否认为它是JSON,然后完全解析 JSON 并读取/解释 EL 并尝试将其应用于 JSON 对象。据我所知,所有这些都将相当昂贵(但 BalusC 可能有不同的想法)

新的 JSON EL 解析器
第二个更好的解决方案是将字符串转换为您选择的 JSON 对象(Java 中有很多对象,包括标准化的“JSON-P”,因为 Java EE 7 和 Java EE 8 的更新版本) .据我所知,没有默认包含的 EL 解析器知道如何在 EL 中处理这些,但examples exist for the non standardized EL formats 不知道这将如何执行,测试是知道的。

现有的 EL 解析器
第三种选择是将 JSON 转换为正常强类型对象,然后让正常的现有解析器对它们进行操作。这可以是默认的现有 java 类型,如 MapListString 和其他正常值,但它甚至可以是更强的类型,如 PersonOrder,将 JSON 字符串转换为强类型对象是一个在 Java EE 8, JSON-B 之前存在于非标准化 JSON 库中但默认 Java(EE) 中不存在的功能。这还有一个额外的优势,即代码完成工作和验证工作在 IDE 中工作

关于写作的解决方案...

由于您似乎确实想将结果写回 JSON 字符串(您的示例中有一个输入),第一个读取解决方案很难扩展到写入,如果可能的话,它会完全破坏优势您似乎不想编写代码来使用它。第二种和第三种解决方案都可能有效,但第三种的优点是可以实现输入验证,例如 bean 验证等。

【讨论】:

    【解决方案2】:

    创建一个类:

    public class JsonWrapper {
    
        JsonObject o;
    
        public JsonWrapper(String s) {
            this(new JsonParser().parse(s).getAsJsonObject());
        }
    
        public JsonWrapper(JsonObject o) {
            this.o = o;
        }
    
        public String getJsonText() {
            return o.getAsString();
        }
    
        public DataWrapper get(String field) {
            return new DataWrapper(field);
        }
    
    
        public class DataWrapper {
    
            String field;
    
            public DataWrapper() {
            }
    
            public DataWrapper(String field) {
                this.field = field;
            }
    
            public String getData() {
                return o.get(field).getAsString();
            }
    
            public void setData(String s) {
                o.add(field, new JsonPrimitive(s));
            }
        }
    
    }
    

    将您的直播流转换为这样的对象:

    List<JsonWrapper> jwList = s.stream().map(s1 -> new JsonWrapper(s1)).collect(Collectors.toList());
    setter & getter
    

    在xhtml中使用

    <c:forEach items="#{liveStreamController.liveStream.jwList}" var="jw">
       <h:outputFormat value="#{jw.get('name').data}" />
       <p:inputText value="#{jw.get('order').data}" />
    </c:forEach>
    

    使用修改后的数据:

    List<String> jsonList = jw.stream().map(JsonWrapper::getJsonText).collect(Collectors.toList());
    

    【讨论】:

    • JsonObject 和 JsonParser 是从哪里来的?这如何与日期字段一起使用?布尔值?等等?
    • 对于 DataWrapper 修改 set get type 从 StringObject 并在 setData 中使用类型检查处理转换
    • 好的,但是创建真正的强类型对象并让 json 库绑定它们不是更好吗?这就引出了我评论的第一部分……Java-EE7/8 ?
    • 这是一个小工具,如果你真的需要强类型的对象,你可以将json文本转换成Product类并与xhtml一起使用。 JsonObjectJsonParser 来自 Gson 库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    相关资源
    最近更新 更多