说我有以下课程:
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方法可能更受欢迎.
使用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.
...如果实例需要手动构建,可能是第三方工厂类?以前,(泽西岛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) 让我说我在一个傍晚非常无聊,经过几天的时间盯着电脑显示器,我决定实现一个聚合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,因为这是使用它的唯一函数,并且只是在第一次调用函数时产生开销(尽管对于这个简单的例子,这并不是更好)而不只是在那里放一个巨大的开关声明).无论如何,我都很感激反馈.
我有一个多模块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运行服务器.
在动物园示例中使用旋转:
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) 假设我正在查询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对已接受的解决方案的回答.
我正在使用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到只有\),那么它将完美地工作,但是这似乎不可能.
想象一下,您有一个启动数据库事务的过滤器,处理请求,然后尝试提交事务.
doFilter(...) {
...
transaction.begin();
filterChain.doFilter(request, response);
transaction.commit();
}
Run Code Online (Sandbox Code Playgroud)
使用Jersey,有一些问题:
使用ContainerRequestFilter/ContainerResponseFilter.
public ContainerRequest过滤器(ContainerRequest请求){...}
公共ContainerResponse过滤器(ContainerRequest请求,ContainerResponse响应){...}
这允许异常冒泡到ExceptionMapper,但是通过2个单独的方法/接口拆分逻辑.问题是,如果存在未映射到响应的异常,则永远不会调用ContainerResponseFilter,因此无法清理.
在JAX-RS环境中处理此问题的首选方法是什么?有没有办法配置响应的刷新,还是有一个我忽略的类或接口?
理想情况下,它将看起来像这样:
List<String> props = objectMapper.getKnownProperties(MyPojo.class);
Run Code Online (Sandbox Code Playgroud)
,,没有这样的方法。通常可行的方法是将Include.ALWAYS显式设置为ObjectMapper的默认值,以反射方式实例化该类的实例,将其转换为映射,然后检查键集。但是,类仍可以覆盖给定注释的ObjectMapper的include行为。
有没有更优雅的方法?至少,有没有一种方法可以使用对象映射器覆盖类注释?
编辑:
只是为了澄清,这些pojos / javabeans / DTO是为与Jackson一起使用而设计的,并且已经绑定了注释以导致特定的序列化行为。碰巧的是,我需要动态地预先知道自己可能会遇到什么,理想情况下,无需复制杰克逊已经可用的信息。也就是说,如果另一个框架提供此功能,我很想知道。:)
我有一个 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 字符串中?到目前为止,我发现了两种方法:
SerializationFeature.WRITE_NULL_MAP_VALUES禁用。这似乎效率低下且笨拙。我尝试注册一个JsonSerializerfor NullNode,但它似乎没有被使用。我注意到它NullNode本身实现了JsonSerializable,它只是委托给SerializerProvider的空值序列化器。我犹豫要不要覆盖它,我觉得应该在序列化值之前进行空过滤,但我没有深入了解它是如何工作的。
有没有更好的办法?
假设我有一个名为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)