这就是我正在做的事情.我想通过Ajax将multipart文件上传到我的Spring网络应用程序.当服务器收到POST请求时,它会在数据库中创建一个票号.然后它启动一个处理实际文件上传的线程.然后服务器返回票号.
我使用CommonsMultipartResolver来处理请求,我已将resolveLazily标志设置为true,以便不立即解决Multipart.
所以这就是我所拥有的东西
@Controller
public class myController{
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public String upload(MultipartHttpServletRequest request, String fileName){
String ticket = dao.createUploadTicket(fileName);
Runnable run = new Runnable(){
@Override
public void run(){
dao.writeUpdate(ticket, "Getting data from request");
final MultipartFile file = request.getFile("theFile");
dao.writeUpdate(ticket, "Multipart file processed");
try {
dao.writeUpdate(ticket, "Saving file to disk");
file.transferTo(new File("/myDirectory"));
dao.writeUpdate(ticket, "File saved to disk");
}
catch(Exception e){
dao.writeUpdate(ticket, "File upload failed with the exception " + e.toString());
}
}
}; …Run Code Online (Sandbox Code Playgroud) java asynchronous file-upload spring-mvc apache-commons-fileupload
我有一个使用Hibernate和PostgreSQL的Spring应用程序.它还使用Spring AMQP(RabbitMQ).
我使用Hibernate事务管理器配置如下:
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" p:dataSource-ref="dataSource" />
Run Code Online (Sandbox Code Playgroud)
我正在使用SimpleMessageListenerContainer进行异步消息接收,配置如下:
@Resource(name="transactionManager")
private PlatformTransactionManager txManager;
@Autowired
private MyListener messageListener;
@Bean
public SimpleMessageListenerContainer mySMLC()
{
final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(rabbitConnectionFactory);
container.setQueueNames("myQueue");
final MessageListenerAdapter adapter = new MessageListenerAdapter(messageListener);
adapter.setMessageConverter(converter);
container.setMessageListener(adapter);
container.setChannelTransacted(true);
container.setTransactionManager(txManager);
return container;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上我已经指定消息的接收需要是事务性的.消息侦听器调用一个服务,该服务可以使用@Transactional注释方法,并可能在数据库上执行CRUD操作.
我的问题是,使用HibernateTransactionManager来管理SimpleMessageListenerContainer级别的事务是否存在问题?使用数据库事务管理器包装从RabbitMQ接收消息会有任何问题吗?
我不期待XA在这里.我只想确保如果服务对数据库的任何操作失败,则消息不会被送到RabbitMQ代理.
我有以下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="com.abc" />
<task:annotation-driven executor="executor"/>
<task:executor id="executor" pool-size="2"/>
</beans>
Run Code Online (Sandbox Code Playgroud)
然后是下面的课
public class SomeClassImpl implements SomeClass {
@Async
@Override // overridden from the interface
public void doSomething(){
System.out.println("doing something async");
}
}
Run Code Online (Sandbox Code Playgroud)
一个测试:
@ContextConfiguration("classpath:test-config.xml") // with the xml config above
@RunWith(value = SpringJUnit4ClassRunner.class)
public class SomeClassTest {
@Autowired
private SomeClass someClass;
@Test
public void testSomething() throws Exception {
System.out.println("Calling doSomething");
someClass.doSomething();
Thread.sleep(5000);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,一切都按预期工作.但是当我调用someClass.doSomething()时,我附加了调试器以逐步执行实际发生的事情,我注意到以下内容:

为什么SimpleAsyncTaskExecutor正在创建4个线程?我知道如果我从task:annotation-driven …
asynchronous ×1
file-upload ×1
java ×1
rabbitmq ×1
spring ×1
spring-amqp ×1
spring-mvc ×1
spring-orm ×1