功能:一个基于JavaWeb的网上书店的设计与实现,归纳 出了几个模块,首先是登录注册模块,图书查找模块,购 物车模块,订单模块,个人中心模块,用户管理模块,图 书管理模块等。 该项目是javaJeb技术的实战操作,采用了MVC设计模 式,包括基本的entity, jscript, servlet,以及ajax异步请 求,查询分页,持久化层方法的封装等等,对javaweb技 术的巩固很有帮助,为J2EE的学习打下基础,适用于课程 设计,毕业设计。
环境配置: Jdk1.8 + Tomcat8.5 + mysql + Eclispe (IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。
项目技术: JSP + Entity+ Servlert + html+ css + JavaScript + JQuery + Ajax + Fileupload 等等。
书信息管理:
@Controller
@RequestMapping("/book")
public class BookInfoController {
@Autowired
private IBookInfoService bookInfoService;
@Autowired
private BookDescMapper bookDescMapper;
/**
* 查询某一本书籍详情
*
* @param bookId
* @param model
* @return
*/
@RequestMapping("/info/{bookId}")
public String bookInfo(@PathVariable("bookId") Integer bookId, Model model) throws BSException {
//查询书籍
BookInfo bookInfo = bookInfoService.findById(bookId);
//查询书籍推荐列表
List recommendBookList = bookInfoService.findBookListByCateId(bookInfo.getBookCategoryId(), 1, 5);
//查询书籍详情
BookDesc bookDesc = bookDescMapper.selectByPrimaryKey(bookId);
//增加访问量
bookInfoService.addLookMount(bookInfo);
Collections.shuffle(recommendBookList);
model.addAttribute("bookInfo", bookInfo);
model.addAttribute("bookDesc", bookDesc);
model.addAttribute("recommendBookList", recommendBookList);
return "book_info";
}
/**
* 通过关键字和书籍分类搜索书籍列表
*
* @param keywords
* @return
*/
@RequestMapping("/list")
public String bookSearchList(@RequestParam(defaultValue = "", required = false) String keywords,
@RequestParam(defaultValue = "0", required = false) int cateId,//分类Id,默认为0,即不按照分类Id查
@RequestParam(defaultValue = "1", required = false) int page,
@RequestParam(defaultValue = "6", required = false) int pageSize,
Model model) {
keywords = keywords.trim();
PageInfo bookPageInfo = bookInfoService.findBookListByCondition(keywords, cateId, page, pageSize,0);//storeId为0,不按照商店Id查询
model.addAttribute("bookPageInfo", bookPageInfo);
model.addAttribute("keywords", keywords);
model.addAttribute("cateId", cateId);
return "book_list";
}
}
@Configuration
/**
* shiro安全框架
*/
public class ShiroConfig {
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public SecurityManager securityManager(EhCacheManager ehCacheManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
//securityManager.setRememberMeManager(rememberMeManager());
securityManager.setCacheManager(ehCacheManager);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map filterChainDefinitionMap = new LinkedHashMap<>();
//拦截器
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/book/**", "anon");
filterChainDefinitionMap.put("/upload/**", "anon");
filterChainDefinitionMap.put("/page/**", "anon");
filterChainDefinitionMap.put("/user/info", "user");
filterChainDefinitionMap.put("/user/**", "anon");//用户登录注册不需要权限
filterChainDefinitionMap.put("/index/**", "anon");//首页放行
filterChainDefinitionMap.put("/", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/user/logout", "logout");
//:这是一个坑呢,一不小心代码就不好使了;
//
//filterChainDefinitionMap.put("/admin/**", "roles[admin]");//perms[system]
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/page/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
myShiroRealm.setCachingEnabled(true);
//启用身份验证缓存,即缓存AuthenticationInfo信息,默认false
myShiroRealm.setAuthenticationCachingEnabled(true);
//缓存AuthenticationInfo信息的缓存名称 在ehcache.xml中有对应缓存的配置
myShiroRealm.setAuthenticationCacheName("authenticationCache");
//启用授权缓存,即缓存AuthorizationInfo信息,默认false
myShiroRealm.setAuthorizationCachingEnabled(true);
//缓存AuthorizationInfo信息的缓存名称 在ehcache.xml中有对应缓存的配置
myShiroRealm.setAuthorizationCacheName("authorizationCache");
return myShiroRealm;
}
/**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
}
/**
* 凭证匹配器
* (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
* )
*
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
return hashedCredentialsMatcher;
}
/**
* cookie对象;
* rememberMeCookie()方法是设置Cookie的生成模版,比如cookie的name,cookie的有效时间等等。
* @return
*/
/*@Bean
public SimpleCookie rememberMeCookie(){
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//如果httyOnly设置为true,则客户端不会暴露给客户端脚本代码,使用HttpOnly cookie有助于减少某些类型的跨站点脚本攻击;
simpleCookie.setHttpOnly(true);
//记住我cookie生效时间,默认30天 ,单位秒:60 * 60 * 24 * 30
//
simpleCookie.setMaxAge(1800);
return simpleCookie;
}*/
/**
* cookie管理对象;
* rememberMeManager()方法是生成rememberMe管理器,而且要将这个rememberMe管理器设置到securityManager中
* @return
*/
/*@Bean
public CookieRememberMeManager rememberMeManager(){
//System.out.println("ShiroConfiguration.rememberMeManager()");
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));
return cookieRememberMeManager;
}*/
/**
* shiro session的管理
*/
/*@Bean
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(tomcatTimeout*1000);
//设置sessionDao对session查询,在查询在线用户service中用到了
sessionManager.setSessionDAO(sessionDAO());
//配置session的监听
Collection listeners = new ArrayList();
listeners.add(new BDSessionListener());
sessionManager.setSessionListeners(listeners);
//设置在cookie中的sessionId名称
sessionManager.setSessionIdCookie(simpleCookie());
return sessionManager;
}*/
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public EhCacheManager ehCacheManager(CacheManager cacheManager) {
EhCacheManager em = new EhCacheManager();
//将ehcacheManager转换成shiro包装后的ehcacheManager对象
em.setCacheManager(cacheManager);
em.setCacheManagerConfigFile("classpath:ehcache.xml");
return em;
}
}