当前位置: 首页 > 知识库问答 >
问题:

如何访问全局spring ObjectMapper?

楚骞尧
2023-03-14

我正在做一个spring boot应用程序。我有下面的实用程序类,它执行从字符串到Json对象的转换。


public class JsonParser {
  private static ObjectMapper objMapper;
    
    
    private static ObjectMapper getMapper() {
        if (objMapper == null) {
            objMapper = new ObjectMapper();
        }
        return objMapper;
    }
  

  public static <K> K fromJsonToObj(String json, Class<K> kClass) throws IOException {
    return mapper.readValue(json, kClass);
  }
}

在我的一个类中,我使用它如下所示

User user = JsonParser.fromJsonToObj(jsonString, User.class);

但我被告知上述方法不是一个很好的做法,

jackson Objectmapper的最佳实践建议只应在应用程序中创建映射器的一个实例。spring的一部分使用jackson反序列化和序列化附加到请求的请求体,因此它已经有了一个。为了遵循jackson的最佳实践,spring将ObjectMapper公开为bean,以便可以在其他位置访问它。我们希望使用这个对象映射器,而不是创建我们自己的对象映射器。这也允许我们配置单个对象映射器,而不是配置多个对象映射器,以防我们需要在基ObjectMapper之上进行其他配置。

因此,如果我们在静态utils类中确实需要objectMapper,我们应该将该对象映射器作为param传入,并且在服务层或其他任何地方,我们可以使用:

@Autowired
private ObjectMapper objectMapper;

获取全局spring对象映射器。

但我不确定如何进行上述建议的方法。谁能告诉我们什么是正确的方法吗?是否有任何配置,我需要提供。

共有1个答案

韩鸿波
2023-03-14

你就这样让spring自动控制它。

@Service
public class YourService {
    public YourService(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }
}

然后,当spring boot找到这个类时,它将从它创建一个spring bean,并将ObjectMapper注入构造函数中的服务。

当spring boot扫描并找到您的组件时,默认情况下它只会添加到上下文中一次。所以你会得到你想要的。我会建议。不是自己创建一个单例类,而是像这样创建自己的映射器组件。

@Component
public class MapperComponent {
    public MapperComponent(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }
    
    public static <K> K fromJsonToObj(String json, Class<K> kClass) throws IOException {
         return objectMapper.readValue(json, kClass);
    }
}

然后需要映射器的服务将如下所示。

@Service
public class YourService {
    private MapperComponent mapperComponent
    public YourService(MapperComponent mapperComponent) {
        this.mapperComponent = mapperComponent;
    }
}

您无法从spring上下文中从一个单例访问objectmapper,就像您尝试的那样。但是您是对的,您可以在每次调用时将它交给单例,但是当您可以自动调用组件时,您真的需要一个静态类吗?

 类似资料:
  • 问题内容: 如何在其他.go包/文件中的main.go中访问已声明/初始化的变量?不断告诉我变量未定义(我知道全局变量不好,但这只是用作时间戳记) 在main.go中 尝试访问其他.go文件中的StartTime,但保持未定义StartTime 问题答案: 我将改为“注入” starttime变量,否则在软件包之间会有循环依赖关系。 main.go otherpackage.go

  • 问题内容: 我有一个main.go文件,其中有: 在我要声明,可在我的应用程序的任何地方访问的全局变量。有可能吗?我试过了: 但是,即使在同一包中,我也无法访问变量。 问题答案: 在顶层声明变量-在任何函数之外: 由于变量的名称以大写字母开头,因此在导入定义变量的包并使用包名对其进行限定时,变量将在当前包中通过其名称可用-在任何其他包中都可用。 这是另一个示例(同样在Go游乐场中:https :

  • 我正在使用Java、Tomcat和泽西创建一个REST Web应用程序。我正在使用注释(没有web.xml!)我最终使用了这个应用程序配置: 这是我的问题。Web容器有一个全局应用程序对象。我正在将其从应用程序构造函数保存到静态字段中。稍后我需要从其他类访问它(它包含全局配置、全局数据库连接工厂,可能还有其他东西。) 我这样做对吗?我怀疑一定有更好的方法:在处理注释时保存对应用程序的引用。但我不知

  • 问题内容: 我有这个: 我如何才能实际修改全局变量g_c? 问题答案: 通过在访问它的函数中声明它: 在Python文档说这个,有关声明: 全局语句是一个声明,适用于整个当前代码块。

  • 问题内容: 首先,我检查了一下,但没有发现涉及我的问题的文章。 如何在angularJS内置指令中访问预定义的js全局变量? 例如,我在 然后我写一个AngularJS指令: 这实际上是行不通的。 然后我得知我应该使用 所以我在其他地方写了代码: 而且这显然不能正常工作……这就像一个恶性循环。您需要访问预定义的js全局变量,然后需要使用ng-init;为了使用ng-init,您需要访问全局变量。

  • 我在下面定义了一个全局js变量(@Url是ASP.Net MVC html帮助程序,它将转换为字符串值): 如何访问angular2组件中的rootVar?我曾经在Angular1.5中使用窗口服务,在angular2中有类似的方法吗? 具体来说,我想使用该rootVar变量来帮助在该组件中生成templateUrl: