双方的WebSockets和服务器发送的事件能够将数据推送到浏览器.对我来说,他们似乎是竞争技术.他们之间有什么区别?你何时会选择一个而不是另一个?
有了这段代码
@RequestMapping(value = "/bar/foo", method = RequestMethod.GET)
public ResponseEntity<foo> foo() {
Foo model;
...
return ResponseEntity.ok(model);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到以下异常
java.lang.IllegalArgumentException: No converter found for return value of type
Run Code Online (Sandbox Code Playgroud)
我的猜测是,由于杰克逊失踪,该对象无法转换为JSON.我不明白为什么,因为我认为杰克逊是用春季靴子建造的.
然后我试图将Jackson添加到pom.xml但我仍然有同样的错误
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我是否必须更改任何弹簧启动属性才能使其正常工作?
谢谢
在Java 8中,我越来越多地用Collection返回值替换Stream.
那么我曾经拥有过的地方:
public List<Element> getElementList() {
return elements;
}
Run Code Online (Sandbox Code Playgroud)
我现在正在使用:
public Stream<Element> streamElements() {
return elements.stream();
}
Run Code Online (Sandbox Code Playgroud)
我的论点是:
事实上,现在,在我的代码中,返回一个List或一些其他集合明确地认识到用户可能认为该集合是可变的并且期望能够改变它.
显然,使用不可变集合可以实现其中一些.
我的问题是:任何人都可以看到这种设计的任何缺点吗?返回一个不可变集合有什么优势Stream吗?
如果我使用返回 a 的 Spring Data 存储库方法Stream,我总是会收到以下异常:
org.springframework.dao.InvalidDataAccessApiUsageException: You're trying to execute a streaming query method without a surrounding transaction that keeps the connection open so that the Stream can actually be consumed. Make sure the code consuming the stream uses @Transactional or any other way of declaring a (read-only) transaction.
org.springframework.data.jpa.repository.query.JpaQueryExecution$StreamExecution.doExecute(JpaQueryExecution.java:338)
org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:85)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
com.sun.proxy.$Proxy201.findByPodcast(Unknown Source)
<my controller class>$$Lambda$118/2013513791.apply(Unknown Source) …Run Code Online (Sandbox Code Playgroud) 阅读完本文之后,我希望使用Spring将数据库查询结果直接流式传输到JSON响应,以确保内存使用量不变(内存中没有贪婪的加载List).
与使用Hibernate的文章中所做的类似,我组装了一个greetingRepository对象,该对象基于a返回数据库内容的流JdbcTemplate.在该实现中,我在查询时创建了一个迭代器ResultSet,并按如下方式返回流:
return StreamSupport.stream(spliterator(), false).onClose(() -> {
log.info("Closing ResultSetIterator stream");
JdbcUtils.closeResultSet(resultSet);
});
Run Code Online (Sandbox Code Playgroud)
即,如果在构造中声明流,则使用一种onClose()方法保证底层ResultSet将被关闭try-with-resources:
try(Stream<Greeting> stream = greetingRepository.stream()) {
// operate on the stream
} // ResultSet underlying the stream will be guaranteed to be closed
Run Code Online (Sandbox Code Playgroud)
但正如在文章中,我希望这个流由自定义对象映射器(MappingJackson2HttpMessageConverter文章中定义的增强)使用.如果我们把try-with-resources需要放在一边,这可行如下:
@RequestMapping(method = GET)
Stream<GreetingResource> stream() {
return greetingRepository.stream().map(GreetingResource::new);
}
Run Code Online (Sandbox Code Playgroud)
然而,正如一位同事在该文章底部评论的那样,这并没有关闭基础资源.
在Spring MVC的上下文中,我如何从数据库一直流式传输到JSON响应中并仍然保证ResultSet将被关闭?你能提供具体的示例解决方案吗?
java ×3
java-8 ×2
java-stream ×2
spring ×2
hibernate ×1
html5 ×1
jackson ×1
spring-boot ×1
spring-data ×1
spring-jdbc ×1
spring-mvc ×1
transactions ×1
websocket ×1