开发者社区> 问答> 正文

Could not obtain transaction-synchronize?400报错

 

重写了shiro的sessionDao

 

package com.ssfeng.youxia.dao;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import com.ssfeng.youxia.model.YouxiaSessions;

@Repository("shiroSessionDao")
public class ShiroSessionDao extends CachingSessionDAO {
	public BaseDao baseDao;

	@Override
	//@Transactional
	protected void doUpdate(Session session) {
		YouxiaSessions youxiaSessions = baseDao.findById(YouxiaSessions.class, session.getId().toString());
		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
			objectOutputStream.writeObject(session);
			String sessionStr = Base64.encodeToString(out.toByteArray());
			youxiaSessions.setSession(sessionStr);
			System.out.println("session长度:"+sessionStr.length());
			baseDao.update(youxiaSessions);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void doDelete(Session session) {
		baseDao.deleteById(YouxiaSessions.class, session.getId().toString());
	}

	@Override
	//@Transactional
	protected Serializable doCreate(Session session) {
		SessionIdGenerator generator = this.getSessionIdGenerator();
		Serializable id = this.getSessionIdGenerator().generateId(session);
		if (session instanceof SimpleSession) {
			SimpleSession simpleSession = (SimpleSession) session;
			simpleSession.setId(id);
		}
		YouxiaSessions youxiaSessions = new YouxiaSessions();
		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
			objectOutputStream.writeObject(session);
			String sessionStr = Base64.encodeToString(out.toByteArray());
			youxiaSessions.setSession(sessionStr);
			youxiaSessions.setId(id.toString());
			baseDao.save(youxiaSessions);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return id;
	}

	@Override
//本函数在登录成功后访问页面,读取数据库的session报如上错误
	protected Session doReadSession(Serializable sessionId) {
		YouxiaSessions youxiaSessions = baseDao.findById(YouxiaSessions.class, sessionId.toString());

		try {
			ByteArrayInputStream input = new ByteArrayInputStream(Base64.decode(youxiaSessions.getSession()));
			ObjectInputStream objectInputStream = new ObjectInputStream(input);
			Session session = (Session) objectInputStream.readObject();
			return session;
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	public BaseDao getBaseDao() {
		return baseDao;
	}

	@Autowired
	public void setBaseDao(BaseDao baseDao) {
		this.baseDao = baseDao;
	}
}

登录成功后doReadSession方法报错,理论上来说,读方法也不需要事务啊

初步怀疑是shiro配置有问题,附上配置代码

package com.ssfeng.youxia.config;

import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

import com.ssfeng.youxia.shiro.RetryLimitCredentialsMatcher;
import com.ssfeng.youxia.shiro.ShiroCacheManager;
import com.ssfeng.youxia.shiro.realm.SaltAwareRealm;

@Configuration
//@EnableAspectJAutoProxy(proxyTargetClass=true)
@PropertySource({ "classpath:shiroConfig.properties" })
@Import({ /* ShiroBeanConfiguration.class, ShiroAnnotationProcessorConfiguration.class *//*
																							 * , ShiroWebConfiguration.
																							 * class
																							 */
		/* ,ShiroWebFilterConfiguration.class */ })
public class ShiroConfiguration {

	@Autowired
	private ApplicationContext appContext;

	@Autowired
	private Environment environment;

	@Autowired
	@Bean(name = "shiroFilter")
	public ShiroFilterFactoryBean getShiroFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
		ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
		/*
		 * Map<String, Filter> filterMaps = new HashMap<>();
		 * filterMaps.put(DefaultFilter.authc.name(), new FormAuthenticationFilter());
		 * factoryBean.setFilters(filterMaps);
		 */
		factoryBean.setSecurityManager(securityManager);
		factoryBean.setLoginUrl("/app/login");
		/*
		 * factoryBean.setSuccessUrl("/");
		 * factoryBean.setUnauthorizedUrl("/unauthorized");
		 */
		factoryBean.setFilterChainDefinitions("/app/article/list=user");
		// Map<String, String> filterChainDefinitionMap = new HashMap<>();
		// filterChainDefinitionMap.put("/app/article/list", "authc");
		// factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return factoryBean;
	}

	@Autowired
	@Bean(name = "securityManager")
	public DefaultWebSecurityManager getSecurityManager(SaltAwareRealm localRealm, SessionManager sessionManager,
			RememberMeManager rememberMeManager) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(localRealm);
		securityManager.setSessionManager(sessionManager);
		securityManager.setRememberMeManager(rememberMeManager);
		return securityManager;
	}

	@Bean
	@Autowired
	public DefaultWebSessionManager sessionManager(SessionDAO shiroSessionDao) {
		final DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		sessionManager.setGlobalSessionTimeout(43200000);
		sessionManager.setSessionIdCookie(sessionIdCookie());
		sessionManager.setSessionDAO(shiroSessionDao);
		return sessionManager;
	}

	// @Bean
	// public ShiroSessionDao shiroSessionDao() {
	// return new ShiroSessionDao();
	// }

	@Bean
	@Autowired
	public RememberMeManager rememberMeManager(SimpleCookie rememberMeCookie) {
		CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
		// rememberMeManager.setCipherKey(cipherKey);
		rememberMeManager.setCookie(rememberMeCookie);
		return rememberMeManager;
	}

	@Autowired
	@Bean(name = "localRealm")
	@DependsOn("lifecycleBeanPostProcessor")
	public SaltAwareRealm getLocaleRealm(CredentialsMatcher credentialsMatcher) {
		SaltAwareRealm realm = new SaltAwareRealm();
		realm.setCredentialsMatcher(credentialsMatcher);
		return realm;
	}

	@Bean(name = "lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}

	@Autowired
	@Bean
	public MethodInvokingFactoryBean getMethodInvokingFactoryBean(
			org.apache.shiro.mgt.SecurityManager securityManager) {
		MethodInvokingFactoryBean factoryBean = new MethodInvokingFactoryBean();
		factoryBean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
		factoryBean.setArguments(new Object[] { securityManager });
		return factoryBean;
	}

	@Autowired
	@Bean
	@DependsOn({ "lifecycleBeanPostProcessor", "shiroCacheManager" })
	public HashedCredentialsMatcher credentialsMatcher(ShiroCacheManager shiroCacheManager) {
		RetryLimitCredentialsMatcher credentialsMatcher = new RetryLimitCredentialsMatcher();
		// environment.getProperty("algorithm")
		credentialsMatcher.setHashAlgorithmName("MD5");
		// Integer.parseInt(environment.getProperty("iterations"))
		credentialsMatcher.setHashIterations(1024);
		credentialsMatcher.setCacheName("halfHour");
		/*
		 * ShiroCacheManager shiroCacheManager = (ShiroCacheManager)
		 * appContext.getBean("shiroCacheManager");
		 */
		credentialsMatcher.setCacheManager(shiroCacheManager);
		return credentialsMatcher;
	}

	@Bean
	public SimpleCookie sessionIdCookie() {
		SimpleCookie simpleCookie = new SimpleCookie();
		// maxAge=-1 表示浏览器关闭时失效此 Cookie;
		simpleCookie.setMaxAge(-1);
		simpleCookie.setHttpOnly(true);
		simpleCookie.setName("sid");
		return simpleCookie;
	}

	@Bean
	public SimpleCookie rememberMeCookie() {
		SimpleCookie rememberMeCookie = new SimpleCookie();
		rememberMeCookie.setName("rememberMeCookie");
		rememberMeCookie.setHttpOnly(true);
		// 记住一周时间
		rememberMeCookie.setMaxAge(604800);
		return rememberMeCookie;
	}
	/*
	 * <!-- anon 不需要认证 authc 需要认证 user 验证通过或RememberMe登录的都可以 -->
	 */

	@Bean
	@Autowired
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
			org.apache.shiro.mgt.SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

	@Autowired
	@Bean
	public ShiroCacheManager shiroCacheManager(EhCacheCacheManager cacheManager) {
		ShiroCacheManager shiroCacheManager = new ShiroCacheManager();
		shiroCacheManager.setCacheManager(cacheManager);
		return shiroCacheManager;
	}

//    @Bean
//    @DependsOn("lifecycleBeanPostProcessor")
//    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
//        return new DefaultAdvisorAutoProxyCreator();
//    }

	public ApplicationContext getAppContext() {
		return appContext;
	}

	public void setAppContext(ApplicationContext appContext) {
		this.appContext = appContext;
	}

}

 

展开
收起
爱吃鱼的程序员 2020-06-07 17:21:13 456 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        <p>项目全部代码https://gitee.com/liyuhang712/youxia</p>
    
    2020-06-07 17:21:30
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Breaking-Electronic-Locks 立即下载
BREAKING ELECTRONIC LOCKS LIKE 立即下载
Why you should care about data 立即下载