Spring MVC:在@ResponseBody 中将对象转换为基元
Spring MVC: Convert Object to Primitive in @ResponseBody
我想要一个控制器 return 一个对象列表给客户端。一个对象也可以是 MyClass
的一个实例,它基本上是一个带有一堆方法的放大的 long
-value。因此,将 MyClass
转换为它的 long
表示是有意义的。 Spring/Jackson 应该自己进行序列化。
我试图使用 Jackson 的 @Json*
-注释,但找不到任何有用的东西。
这是简化的控制器:
@RequestMapping("/execute")
@ResponseBody
public List<List<Object>> execute() {
return generateResponseBody();
}
内部对象列表由一个字符串、两个数字、一个 MyClass
实例和另外两个字符串组成。虽然原语转换得很好,但 MyClass
总是转换为 JSON-map:
["str1",1337,42,{"asDmy":"13.01.2015","asYmd":"2015.01.13"},"str2","str3"]
不过,我想要
["str1",1337,42,1421164289000,"str2","str3"]
注意:我也尝试使用 Converter
作为一些教程和答案建议:
@Bean
public ConversionServiceFactoryBean conversionService() {
HashSet<Object> converters = new HashSet<>();
converters.add(new Converter<MyClass, Long>() {
@Override
public Long convert(MyClass value) {
return value.getAsMilliseconds();
}
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return SimpleType.construct(MyClass.class);
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return SimpleType.construct(Long.class);
}});
ConversionServiceFactoryBean conversionService = new ConversionServiceFactoryBean();
conversionService.setConverters(converters);
return conversionService;
}
但是,当我创建一个 ConversionServiceFactoryBean
的 bean 时,它会使我的 CXF 在 webapp 启动时崩溃。如果有人关心,这里是堆栈跟踪:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.provider.schemas.cai3g1_2.SessionControl com.mc.config.AppConfig.sessionControl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionControl': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:370)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4971)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.provider.schemas.cai3g1_2.SessionControl com.mc.config.AppConfig.sessionControl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionControl': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 30 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionControl': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1512)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:250)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 32 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:424)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:387)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:354)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:466)
at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1188)
at org.apache.cxf.bus.spring.SpringBeanLocator.getBeansOfType(SpringBeanLocator.java:59)
at org.apache.cxf.bus.CXFBusImpl.getExtension(CXFBusImpl.java:99)
at org.apache.cxf.service.factory.AbstractServiceFactoryBean.setBus(AbstractServiceFactoryBean.java:98)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.initializeServiceFactory(AbstractWSDLBasedEndpointFactory.java:231)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:100)
at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:90)
at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:144)
at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:133)
at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.create(JaxWsProxyFactoryBeanDefinitionParser.java:78)
at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.getObject(JaxWsProxyFactoryBeanDefinitionParser.java:82)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
... 40 more
我怎样才能做到这一点?
@JsonUnwrapped
和 @JsonAutoDetect
应该可以帮到你。查看文档:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
您可以编写自定义序列化程序并使用自定义序列化程序注释您的 MyClass,例如
public class CustomSerializer extends JsonSerializer<MyClass> {
@Override
public void serialize(MyClass myClass, JsonGenerator generator,
SerializerProvider provider) throws IOException {
String dateString = String.valueOf(myClass.getDateTime().getMillis());
generator.writeString(dateString);
}
}
和
@JsonSerialize(using = CustomSerializer.class)
public class MyClass {
private DateTime dateTime = new DateTime();
...
public DateTime getDateTime() {
return dateTime;
}
public void setDateTime(DateTime dateTime) {
this.dateTime = dateTime;
}
}
不确定 class 中字段的确切类型,但您明白了要点
我想要一个控制器 return 一个对象列表给客户端。一个对象也可以是 MyClass
的一个实例,它基本上是一个带有一堆方法的放大的 long
-value。因此,将 MyClass
转换为它的 long
表示是有意义的。 Spring/Jackson 应该自己进行序列化。
我试图使用 Jackson 的 @Json*
-注释,但找不到任何有用的东西。
这是简化的控制器:
@RequestMapping("/execute")
@ResponseBody
public List<List<Object>> execute() {
return generateResponseBody();
}
内部对象列表由一个字符串、两个数字、一个 MyClass
实例和另外两个字符串组成。虽然原语转换得很好,但 MyClass
总是转换为 JSON-map:
["str1",1337,42,{"asDmy":"13.01.2015","asYmd":"2015.01.13"},"str2","str3"]
不过,我想要
["str1",1337,42,1421164289000,"str2","str3"]
注意:我也尝试使用 Converter
作为一些教程和答案建议:
@Bean
public ConversionServiceFactoryBean conversionService() {
HashSet<Object> converters = new HashSet<>();
converters.add(new Converter<MyClass, Long>() {
@Override
public Long convert(MyClass value) {
return value.getAsMilliseconds();
}
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return SimpleType.construct(MyClass.class);
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return SimpleType.construct(Long.class);
}});
ConversionServiceFactoryBean conversionService = new ConversionServiceFactoryBean();
conversionService.setConverters(converters);
return conversionService;
}
但是,当我创建一个 ConversionServiceFactoryBean
的 bean 时,它会使我的 CXF 在 webapp 启动时崩溃。如果有人关心,这里是堆栈跟踪:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.provider.schemas.cai3g1_2.SessionControl com.mc.config.AppConfig.sessionControl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionControl': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:370)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4971)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.provider.schemas.cai3g1_2.SessionControl com.mc.config.AppConfig.sessionControl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionControl': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 30 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionControl': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1512)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:250)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 32 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'conversionService': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:424)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:387)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:354)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:466)
at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1188)
at org.apache.cxf.bus.spring.SpringBeanLocator.getBeansOfType(SpringBeanLocator.java:59)
at org.apache.cxf.bus.CXFBusImpl.getExtension(CXFBusImpl.java:99)
at org.apache.cxf.service.factory.AbstractServiceFactoryBean.setBus(AbstractServiceFactoryBean.java:98)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.initializeServiceFactory(AbstractWSDLBasedEndpointFactory.java:231)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:100)
at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:90)
at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:144)
at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:133)
at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.create(JaxWsProxyFactoryBeanDefinitionParser.java:78)
at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.getObject(JaxWsProxyFactoryBeanDefinitionParser.java:82)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
... 40 more
我怎样才能做到这一点?
@JsonUnwrapped
和 @JsonAutoDetect
应该可以帮到你。查看文档:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
您可以编写自定义序列化程序并使用自定义序列化程序注释您的 MyClass,例如
public class CustomSerializer extends JsonSerializer<MyClass> {
@Override
public void serialize(MyClass myClass, JsonGenerator generator,
SerializerProvider provider) throws IOException {
String dateString = String.valueOf(myClass.getDateTime().getMillis());
generator.writeString(dateString);
}
}
和
@JsonSerialize(using = CustomSerializer.class)
public class MyClass {
private DateTime dateTime = new DateTime();
...
public DateTime getDateTime() {
return dateTime;
}
public void setDateTime(DateTime dateTime) {
this.dateTime = dateTime;
}
}
不确定 class 中字段的确切类型,但您明白了要点