小编Sha*_*aun的帖子

什么是杰克逊反序列化相当于@JsonUnwrapped?

说我有以下课程:

public class Parent {
  public int age;
  @JsonUnwrapped
  public Name name;
}
Run Code Online (Sandbox Code Playgroud)

生成JSON:

{
  "age" : 18,
  "first" : "Joey",
  "last" : "Sixpack"
}
Run Code Online (Sandbox Code Playgroud)

如何将其反序列化为Parent类?我可以使用@JsonCreator

@JsonCreator
public Parent(Map<String,String> jsonMap) {
  age = jsonMap.get("age");
  name = new Name(jsonMap.get("first"), jsonMap.get("last"));
}
Run Code Online (Sandbox Code Playgroud)

但这也有效地添加@JsonIgnoreProperties(ignoreUnknown=true)到Parent类,因为所有属性都映射到此处.因此,如果您希望未知的JSON字段引发异常,则必须自己执行此操作.此外,如果地图值可能不是字符串,则必须进行一些手动类型检查和转换.杰克逊有办法自动处理这个案子吗?

编辑: 我可能会疯狂,但这实际上似乎工作,尽管文档中没有明确提到:http://fasterxml.github.io/jackson-annotations/javadoc/2.2.0/com/fasterxml/jackson/annotation/ JsonUnwrapped.html
我很确定它之前对我不起作用.尽管如此,当需要自定义逻辑来反序列化未包装的多态类型时,建议的@JsonCreator方法可能更受欢迎.

java json jackson deserialization

39
推荐指数
3
解决办法
2万
查看次数

使用JPA Criteria API,您是否可以执行只获得一次连接的获取连接?

使用JPA 2.0.似乎默认情况下(没有显式提取),@OneToOne(fetch = FetchType.EAGER)在1 + N个查询中提取字段,其中N是包含定义与不同相关实体的关系的实体的结果数.使用Criteria API,我可能会尝试避免如下:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyEntity> query = builder.createQuery(MyEntity.class);
Root<MyEntity> root = query.from(MyEntity.class);
Join<MyEntity, RelatedEntity> join = root.join("relatedEntity");
root.fetch("relatedEntity");
query.select(root).where(builder.equals(join.get("id"), 3));
Run Code Online (Sandbox Code Playgroud)

理想情况下,上述内容应与以下内容相同:

SELECT m FROM MyEntity m JOIN FETCH myEntity.relatedEntity r WHERE r.id = 3
Run Code Online (Sandbox Code Playgroud)

但是,条件查询导致根表不必要地连接到相关实体表两次; 一次用于获取,一次用于where谓词.生成的SQL看起来像这样:

SELECT myentity.id, myentity.attribute, relatedentity2.id, relatedentity2.attribute 
FROM my_entity myentity 
INNER JOIN related_entity relatedentity1 ON myentity.related_id = relatedentity1.id 
INNER JOIN related_entity relatedentity2 ON myentity.related_id = relatedentity2.id 
WHERE relatedentity1.id = 3
Run Code Online (Sandbox Code Playgroud)

唉,如果我只进行获取,那么我没有在where子句中使用的表达式.

我错过了什么,或者这是Criteria API的限制?如果是后者,这是否在JPA 2.1中得到纠正,还是有任何特定于供应商的增强功能?

否则,最好放弃编译时类型检查(我意识到我的示例不使用元模型)并使用动态JPQL TypedQueries.

java jpa jpql criteria-api

24
推荐指数
2
解决办法
5万
查看次数

使用Jersey 2.0,如何为每个请求注册一个可绑定实例?

...如果实例需要手动构建,可能是第三方工厂类?以前,(泽西岛1.x),你会做这样的事情:

public class MyInjectableProvider extends PerRequestTypeInjectableProvider<Context, MyInjectable> {
    public MyInjectableProvider() {
        super(MyInjectable.class);
    }

    @Override
    public Injectable<MyInjectable> getInjectable(ComponentContext ic, Context context) {
        MyInjectable myInjectableInstance = //...

        return new Injectable<MyInjectable>() {
            @Override
            public MyInjectable getValue() {
                return myInjectableInstance;
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

匿名本地类能够访问要在某个范围内返回的实例.当您不使用具有默认构造函数的类时,这非常有用,但它们需要基于每个请求构建.

Jersey 2.0切换到HK2作为依赖注入框架,但是,迁移页面(https://jersey.java.net/documentation/latest/migration.html)没有提供这种绑定的示例,并且HK2文档没有提供使用AbstractBinder的示例.

为了进一步阐述,我正在尝试向我的资源提供资源本地的,与容器无关的JPA EntityManager实例.这些必须从单件工厂类中获取,并且应该只针对单个"工作单元",这在我的情况下是一个请求.我知道有解决方法(只是注入工厂,或绑定到threadlocal),但我发现以前的解决方案很优雅,并希望尽可能重新创建它.

编辑:
经过一段时间的HK2 javadocs挖掘后,我发现类似的东西可以实现如下:

public class MyInjectableProvider extends AbstractBinder 
        implements Factory<MyInjectable> {
    @Override
    protected void configure() {
        bindFactory(this).to(MyInjectable.class);
    }

    @Override
    public MyInjectable provide() {
        return getMyInjectable();
    }

    @Override
    public void dispose(MyInjectable instance) {}
} …
Run Code Online (Sandbox Code Playgroud)

java dependency-injection jersey jersey-2.0

22
推荐指数
1
解决办法
7871
查看次数

C++ - 将静态映射初始化为私有类成员

让我说我在一个傍晚非常无聊,经过几天的时间盯着电脑显示器,我决定实现一个聚合C++类来管理绘制像素的颜色,因为我显然已经疯了.对于初学者,我们只是告诉(可能是单身)ColorManager对象我们想要使用的颜色,它将返回一个Color对象,无论可能是什么.一个简单的实现如下:

#include "Color.h"
#include <map>

enum COLOR { RED = 0, BLUE, GREEN, YELLOW, ORANGE, WHITE, BLACK,
    BRICKS_FROM_A_DISTANCE_ON_AN_UNUSUALLY_SUNNY_AFTERNOON,
    // etc
    COLOR_COUNT };

class ColorManager
{
public:
    ColorManager();
    ~ColorManager();
    Color getColor(COLOR color) const;
private:
    typedef std::map<COLOR, Color> ColorMap;
    static ColorMap colorMap;
};
Run Code Online (Sandbox Code Playgroud)

所以,希望这个简单的代码:

ColorManger colorManager;
Color blue = colorManager.getColor(BLUE);
Run Code Online (Sandbox Code Playgroud)

应该让我们真的很容易做任何你需要颜色对象的废话.

问题是您需要在某处初始化静态私有ColorMap,以便每个COLOR枚举对应一个正确的Color对象,VC++ 2010似乎不喜欢您尝试的任何东西.所以问题是,我如何以及在何处初始化此地图?

显然,这是一个人为的例子,但除此之外,或许为一个作为单例的类定义静态变量并不值得.或者,也许,我可能只是在getColor()中声明变量static,因为这是使用它的唯一函数,并且只是在第一次调用函数时产生开销(尽管对于这个简单的例子,这并不是更好)而不只是在那里放一个巨大的开关声明).无论如何,我都很感激反馈.

c++ static stl map

18
推荐指数
3
解决办法
2万
查看次数

是否有一种使用maven运行可执行jar的好方法?

我有一个多模块maven项目,其中一个模块用于分发.

Project \
| moduleA \
| moduleB \
| ...
| dist-module \
Run Code Online (Sandbox Code Playgroud)

该发行版包含一个我想轻松执行的可执行jar.但是,要执行它,我必须输入类似的内容:

java -jar dist-module/target/dist-module-1.0-SNAPSHOT-full-dist/myJar.jar
Run Code Online (Sandbox Code Playgroud)

简单地键入:

mvn exec:java \ OR
mvn exec:exec
Run Code Online (Sandbox Code Playgroud)

不幸的是,我找不到让java目标执行.jar的方法.exec目标实际上是这样做的,但是有一个问题:jar包含一个嵌入式jetty服务器,并且由于exec的工作方式(不使用与maven相同的JVM),服务器不会终止,除非我终止进程手动,这同样令人烦恼.

有关如何使用maven执行此操作的任何建议?

编辑:
为了澄清,该命令主要用于简单的手动烟雾测试; 读取日志输出并确保程序在其分发环境中正确启动.因此,它应该是一个阻塞调用,ctrl-c终止服务器和maven.

嵌入式服务器专门用于运行一些特定的应用程序,并不会自动重新加载它们.因此,不需要长时间独立于maven运行服务器.

java jar build embedded-jetty maven

17
推荐指数
1
解决办法
3万
查看次数

杰克逊多态反序列化 - 您是否可以要求存在字段而不是特定值?

在动物园示例中使用旋转:

public class ZooPen {
    public String type;
    public List<Animal> animals;
}

public class Animal {
    public String name;
    public int age;
}

public class Bird extends Animal {
    public double wingspan;
}
Run Code Online (Sandbox Code Playgroud)

如果没有指定翼展,我想使用多态反序列化来构造Animal实例,如果是,则使用Bird实例.在Jackson中,无类型反序列化通常看起来像这样:

@JsonTypeInfo( 
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "wingspan",
    visible = true,
    defaultImpl = Animal.class
)
@JsonSubTypes({
    @Type(value = Bird.class, name = **???**)
})  
public class Animal {
    ...
}
Run Code Online (Sandbox Code Playgroud)

翼展值可以是任何东西,如果没有特定匹配的东西,杰克逊会回到defaultImpl类.

我可以使用@JsonCreator

@JsonCreator
public static Animal create(Map<String,Object> jsonMap) 
        throws JsonProcessingException {

    ObjectMapper mapper = new …
Run Code Online (Sandbox Code Playgroud)

java polymorphism json jackson deserialization

14
推荐指数
2
解决办法
1982
查看次数

XPath - 除了第一个特定元素之外的所有后续兄弟

假设我正在查询xhtml文档,我想查询表后面的所有兄弟姐妹id='target'.此外,我既不想要第一个<table>兄弟姐妹也不想要<ol>这个特定元素的第一个兄弟姐妹.这是我能想到的最好的:

//table[@id='target']/following-sibling::*[not(self::table[1]) and not(self::ol[1])]
Run Code Online (Sandbox Code Playgroud)

但是,这应该没有返回任何结果.显然我不理解这方面的一些语法(我找不到一个好的信息来源).如果有经验丰富的XPath语法的人能帮到我,我当然会感激不尽.另外,出于纯粹的学术目的,我很好奇上面的内容实际上是做什么的.

更新:
请参阅LarsH的答案,解释为什么我的XPath无法正常工作,并看到Dimitre对已接受的解决方案的回答.

xml xhtml xpath

9
推荐指数
1
解决办法
2万
查看次数

PHP:什么是解析包含很长行的文本文件的有效方法?

我正在使用php中的解析器,它旨在从文本文件中提取MySQL记录.一个特定的行可能以一个字符串开头,该字符串对应于需要插入记录(行)的表,然后是记录本身.记录由反斜杠分隔,字段(列)用逗号分隔.为简单起见,我们假设我们有一个表格,代表我们数据库中的人,其中的字段是名字,姓氏和职业.因此,文件的一行可能如下所示

[People] ="\ Han,Solo,Smuggler\Luke,Skywalker,Jedi ......"

省略号(...)可能是额外的人.一种简单的方法可能是用于fgets()从文件中提取一行,并用于preg_match()从该行中提取表名,记录和字段.

但是,我们假设我们有很多星球大战的角色需要跟踪.事实上,这一行很多,最终会有200,000多个字符/字节长.在这种情况下,采用上述方法提取数据库信息似乎效率低下.您必须首先将数十万个字符读入内存,然后读这些相同的字符以查找正则表达式匹配.

有没有一种方法,类似于使用文件构造String next(String pattern)Scanner类的Java 方法,允许您在扫描文件时在线匹配模式?

这个想法是你不必扫描相同的文本两次(从文件中读取它到字符串,然后匹配模式)或冗余地将文本存储在内存中(在文件行字符串和匹配中)模式).这甚至会使性能显着提高吗?很难确切知道PHP或Java在幕后做了什么.

Onfgetcsv()
此功能可以很容易地根据某些分隔符在文件中拆分行,并且我确定它在扫描文件时逐个字符地检查分隔符.然而,问题是我正在寻找基本上两个分隔符,并且fgetcsv()只接受一个分隔符.例如:

我可以使用','作为分隔符.如果我将文件格式更改为也使用反斜杠的逗号,我可以将整行读入字段数组.那么问题是,我需要重申所有字段以确定记录的开始和结束位置以及准备sql.类似地,如果我使用'\'作为分隔符(单个反斜杠,在此处进行转义),那么我需要重复所有记录以提取字段并准备sql.

我所试图做的是检查在最大性能一举逗号和反斜杠(也许还有其他的东西,如[表名]).如果fgetcsv()允许我指定多个分隔符(或正则表达式)或允许我更改它认为是"行尾"(从\n或\n\r到只有\),那么它将完美地工作,但是这似乎不可能.

php csv performance file-io parsing

8
推荐指数
1
解决办法
2051
查看次数

你能用JAX-RS/Jersey做传统的Servlet过滤吗?

想象一下,您有一个启动数据库事务的过滤器,处理请求,然后尝试提交事务.

doFilter(...) {
    ...
    transaction.begin();
    filterChain.doFilter(request, response);
    transaction.commit();
}
Run Code Online (Sandbox Code Playgroud)

使用Jersey,有一些问题:

  1. 使用过滤器,Jersey Servlet容器在执行返回过滤器之前提交/刷新响应.因此,如果提交失败,则无法将返回代码修改为失败.此外,JAX-RS ExceptionMapper不会捕获异常.
  2. 使用ContainerRequestFilter/ContainerResponseFilter.

    public ContainerRequest过滤器(ContainerRequest请求){...}
    公共ContainerResponse过滤器(ContainerRequest请求,ContainerResponse响应){...}

这允许异常冒泡到ExceptionMapper,但是通过2个单独的方法/接口拆分逻辑.问题是,如果存在未映射到响应的异常,则永远不会调用ContainerResponseFilter,因此无法清理.

在JAX-RS环境中处理此问题的首选方法是什么?有没有办法配置响应的刷新,还是有一个我忽略的类或接口?

java jax-rs jersey java-ee servlet-filters

5
推荐指数
1
解决办法
2884
查看次数

使用Jackson,如何为任意pojo类获取已知JSON属性的列表?

理想情况下,它将看起来像这样:

List<String> props = objectMapper.getKnownProperties(MyPojo.class);
Run Code Online (Sandbox Code Playgroud)

,,没有这样的方法。通常可行的方法是将Include.ALWAYS显式设置为ObjectMapper的默认值,以反射方式实例化该类的实例,将其转换为映射,然后检查键集。但是,类仍可以覆盖给定注释的ObjectMapper的include行为。

有没有更优雅的方法?至少,有没有一种方法可以使用对象映射器覆盖类注释?

编辑:
只是为了澄清,这些pojos / javabeans / DTO是为与Jackson一起使用而设计的,并且已经绑定了注释以导致特定的序列化行为。碰巧的是,我需要动态地预先知道自己可能会遇到什么,理想情况下,无需复制杰克逊已经可用的信息。也就是说,如果另一个框架提供此功能,我很想知道。:)

java json jackson

5
推荐指数
2
解决办法
1441
查看次数

序列化 Jackson JSON 树模型时排除 NullNode

我有一个 pojo 类型,它需要在序列化时将特定数值设置为特殊字符串。这些值将始终为空,可能非常深入层次结构。

为了实现这一点,我首先将 pojo 转换为具有完整空值的 JsonNode 以保留属性顺序,然后我遵循结构中的路径来设置一些字符串并根据需要创建节点。最后,我让 ObjectMapper 将 JsonNode 序列化为字符串。逻辑看起来像这样:

ObjectMapper nonNullMapper = new ObjectMapper();
nonNullMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

ObjectMapper includeAllMapper = new ObjectMapper();
includeAllMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

// NullNodes create stubs to maintain property order
JsonNode node = includeAllMapper.valueToTree(pojoInstance);
insertStrings(node);

String json = nonNullMapper.writeValueAsString(node); 
// Halp, there's still nulls
Run Code Online (Sandbox Code Playgroud)

请注意,我知道有一个 @JsonInclude注释,所以我实际上并不需要两个映射器,但事实证明我想在其他地方序列化没有空值的 pojo 实例,所以我无法使用它。

无论如何,如何避免将 NullNodes 序列化到我的 json 字符串中?到目前为止,我发现了两种方法:

  1. 转换为 Map,然后序列化为 String,使用 SerializationFeature.WRITE_NULL_MAP_VALUES禁用。这似乎效率低下且笨拙。
  2. 在序列化 JsonNode 之前手动删除 NullNode 实例。鉴于支持排除 pojo 和地图的空值,似乎没有必要,并且它增加了(也许?)不必要的复杂性。

我尝试注册一个JsonSerializerfor NullNode,但它似乎没有被使用。我注意到它NullNode本身实现了JsonSerializable,它只是委托给SerializerProvider的空值序列化器。我犹豫要不要覆盖它,我觉得应该在序列化值之前进行空过滤,但我没有深入了解它是如何工作的。

有没有更好的办法?

java json jackson

5
推荐指数
2
解决办法
4925
查看次数

C++ - 在不引入紧耦合的情况下识别一族多态类

假设我有一个名为Component的抽象基类,它是GUI组件层次结构的根.在这种情况下,我们可能有两个子类,Button和Label,它们都是抽象类,并作为各自具体类层次结构的根存在.

从Button继承的具体类可能包括RoundButton和SquareButton.

从Label继承的具体类可能包括TextLabel和PictureLabel.

最后,假设有一个聚合Container类,它包含一组Component对象.

问题是我有指向Component对象的指针,但我需要将它们标识为Buttons或Labels.例如,如果我想指定所有Buttons的内部文本应该有一个更大的字体,我可以迭代Container中的所有Component对象,并以某种方式确定哪些是按钮,并调用一些特定于按钮的方法.

这些组件"系列"标识自己的一种方法是使用字符串.

class Component {
public:
    virtual char const * const getFamilyID() const = 0;
};

// In Button.h
char const * const COMPONENT_BUTTON = "button";

class Button : public Component {
public:
    virtual char const * const getFamilyID() const { return COMPONENT_BUTTON; };
};

// Code sample
if (strcmp(component->getFamilyID(),COMPONENT_BUTTON) == 0)
    // It's a button!
Run Code Online (Sandbox Code Playgroud)

这是松散耦合的,因为该组件的任务是为这些家庭定义这些家庭; 它不需要了解哪些家庭存在.客户端需要知道不同的组件系列,但如果它尝试针对某些操作来定位特定的组件系列,那么这是无法避免的.

但是,假设我们有非常高的性能要求,我们希望避免比较字符串.避免将此功能设置为虚拟也很好,以便我们可以内联它.此外,如果Component的每个子类都需要声明一个全局常量,那么以某种方式修改Component类以使其成为需求或使其不必要可能会很好.

解决此问题的一种方法是在Component.h中定义一个枚举器

enum COMPONENT_FAMILY {
    COMPONENT_BUTTON = 0,
    COMPONENT_LABEL,
    // etc...
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,getFamilyID()只能返回COMPONENT_FAMILY枚举,我们基本上只能比较整数.不幸的是,这意味着任何新的组件系列都必须在此枚举中"注册",这很容易但对其他程序员来说并不完全直观.此外,该方法仍然必须是虚拟的,除非我们创建一个我们知道将具有极低基数(非理想)的非静态COMPONENT_FAMILY成员.

什么是解决这个问题的好方法?在我的情况下,性能是关键,虽然类似于枚举解决方案似乎很容易,但我想知道我是否忽略了更好的方法.

---编辑---
我意识到我应该指出,在实际系统中,Container等价物只能存储每个族的1个组件.因此,组件实际上存储在地图中,例如:

std:map<COMPONENT_FAMILY, Component*> …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism decoupling

2
推荐指数
1
解决办法
445
查看次数