工程搭建分析
freight-parent:父工程,打包方式pom,管理jar包的版本号。所有module都应该继承父工程。
为什么不在freight-parent定义所有jar包,而是定义版本号呢?
项目部署到tomcat需要打war包,如果这个项目依赖了所有的jar包则会非常大,导致传输非常慢。
|-- freight:聚合(pom)
|-- freight - common:通用的工具类(jar)
|-- freight - pojo:子工程(jar)
|-- freight - dao:子工程(jar)
|-- freight - service:子工程(jar)
|-- freight - web:子工程(war)
1. 用户登录
1.1 系统静态页面
1.2 pdm
1.3 pojo
逆向工程生成
1.4 mapper
逆向工程生成
1.5 service
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserPMapper userPMapper;
@Autowired
private DeptPMapper deptPMapper;
@Autowired
private ModulePMapper modulePMapper;
@Autowired
private UserInfoPMapper userInfoPMapper;
@Override
public UserP login(String username) {
UserPExample userPExample = new UserPExample();
UserPExample.Criteria criteria = userPExample.createCriteria();
criteria.andUserNameEqualTo(username);
List<UserP> user = userPMapper.selectByExample(userPExample);
if (user !=null){
return user.get(0);
}
return null;
}
@Override
public CurrentUser findUserInfoDeptByUser(UserP user){
CurrentUser currentUser = new CurrentUser();
currentUser.setUser(user);// 设置用户基本信息
currentUser.setDept(deptPMapper.selectByPrimaryKey(user.getDeptId()));// 设置用户所属部门信息
currentUser.setUserInfo(userInfoPMapper.selectByPrimaryKey(user.getUserId()));// 设置用户详细信息
return currentUser;
}
@Override
public List<ModuleP> getPermissionsByUserId(String userid){
return modulePMapper.getPermissionsByUserId(userid);
}
}
1.6 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- springmvc的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--启动shiro-->
<filter>
<filter-name>shiro</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiro</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
1.7 applicationContext-shiro.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="loginUrl" value="/index"></property>
<!--注入安全管理器-->
<property name="securityManager" ref="securityManager"></property>
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter"></entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
<!--登录页匿名访问-->
/ = anon
<!--静态资源匿名访问-->
/js/** = anon
/css/** = anon
/images/** = anon
/skin/** = anon
/components/** = anon
/favicon.ico = anon
<!--表单认证过滤器-->
/user/login = authc
<!--退出-->
/user/logout = logout
/** = user
</value>
</property>
</bean>
<bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
<property name="usernameParam" value="username"></property>
<property name="passwordParam" value="password"></property>
<property name="loginUrl" value="/user/login"></property>
<property name="successUrl" value="/main"></property>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--注入自定义realm-->
<property name="realm" ref="customRealm"></property>
<!--注入缓存管理器-->
<property name="cacheManager" ref="cacheManager"></property>
<!--注入sessionManager-->
<property name="sessionManager" ref="sessionManager"></property>
</bean>
<!--注入自定义realm-->
<bean id="customRealm" class="com.y.realm.CustomRealm">
<!--注入密码匹配器-->
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!--密码匹配器-->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"></property>
<property name="hashIterations" value="1"></property>
</bean>
<!--会话管理器-->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="1800000"></property>
</bean>
<!--缓存管理器-->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml" />
</bean>
</beans>
1.8 realm
public class CustomRealm extends AuthorizingRealm{
@Autowired
private UserService userService;
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username = (String) authenticationToken.getPrincipal();
//查询用户名
UserP user = userService.login(username);
if(user==null){
return null;
}
CurrentUser currentUser = userService.findUserInfoDeptByUser(user);
currentUser.setUser(user);
//从数据库中获取密码
String pwd = user.getPassword();
//从数据库中获取盐
String salt ="1";
//返回认证信息
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, pwd,
ByteSource.Util.bytes(salt), getName());
return authenticationInfo;
}
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
// 获取用户
UserP userP = (UserP) principal.getPrimaryPrincipal();
CurrentUser currentUser = userService.findUserInfoDeptByUser(userP);
UserP user = currentUser.getUser();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 填充用户权限
List<ModuleP> modulePList = userService.getPermissionsByUserId(user.getUserId());
if (modulePList != null && modulePList.size() > 0) {
for (ModuleP m : modulePList) {
authorizationInfo.addStringPermission(m.getCpermission());
}
}
return authorizationInfo;
}
//清除缓存
public void clearCached() {
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
super.clearCache(principals);
}
}
1.9 controller
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
//认证失败,成功不调用
@RequestMapping("/login")
public String login(HttpServletRequest request, Model model){
String shiroLoginFailure = (String) request.getAttribute("shiroLoginFailure");
if(UnknownAccountException.class.getName().equals(shiroLoginFailure)){
model.addAttribute("errorInfo","账号不存在!!!");
}else if(IncorrectCredentialsException.class.getName().equals(shiroLoginFailure)){
model.addAttribute("errorInfo","密码错误!!!");
}
return "index";
}
}
1.10 index.jsp
修改登录地址
<div class="btnstyle">
<input class="loginImgOut" value="" type="button"
onclick="formSubmit('${ctx}/user/login','_self');"
onmouseover="this.className='loginImgOver'"
onmouseout="this.className='loginImgOut'"
/>
<input class="resetImgOut" value="" type="button"
onmouseover="this.className='resetImgOver'"
/>
</div>
显示异常信息
<div class="erro" id="erro">
<div class="erro_intro">
${errorInfo}
</div>
</div>
2. 主页面
2.1 登录成功显示主页面
2.1.2 修改PageController
@Controller
public class PageController {
@Autowired
private UserService userService;
@RequestMapping("/")
public String showIndex(){
return "index";
}
@RequestMapping("/main")
public String showMaim(){
return "home/fmain";
}
@RequestMapping("/homeAction_title")
public String homeActionTitle(Model model){
Subject subject = SecurityUtils.getSubject();
UserP userP = (UserP) subject.getPrincipal();
CurrentUser currentUser = userService.findUserInfoDeptByUser(userP);
model.addAttribute("currentUser",currentUser);
return "home/title";
}
@RequestMapping("/homeAction_toleft")
public String homeActionToleft(String moduleName)
{
return moduleName+"/left";
}
@RequestMapping("/homeAction_tomain")
public String homeActionTomain(String moduleName){
return moduleName+"/main";
}
}
2.2 主页面布局分析
frameset实现主页面布局:
<frameset rows="125,*" name="topFrameset" border="0">
<frame name="top_frame" scrolling="no" target="middleFrameSet" src="homeAction_title">
<frameset cols="202,*" height="100%" name="middle" frameborder="no" border="0" framespacing="0">
<frame name="leftFrame" class="leftFrame" target="main" scrolling="no" src="homeAction_toleft?moduleName=home" />
<frame name="main" class="rightFrame" src="homeAction_tomain?moduleName=home" />
</frameset>
</frameset>
2.3 创建PageController
@Controller
public class PageController {
@Autowired
private UserService userService;
@RequestMapping("/")
public String showIndex(){
return "index";
}
@RequestMapping("/main")
public String showMaim(){
return "home/fmain";
}
//标题栏菜单
@RequestMapping("/homeAction_title")
public String homeActionTitle(Model model){
Subject subject = SecurityUtils.getSubject();
UserP userP = (UserP) subject.getPrincipal();
CurrentUser currentUser = userService.findUserInfoDeptByUser(userP);
model.addAttribute("currentUser",currentUser);
return "home/title";
}
//跳转左侧菜单
@RequestMapping("/homeAction_toleft")
public String homeActionToleft(String moduleName)
{
return moduleName+"/left";
}
//跳转主窗口
@RequestMapping("/homeAction_tomain")
public String homeActionTomain(String moduleName){
return moduleName+"/main";
}
}
2.4.1展示当前登录用户信息
2.4.1 创建CurrentUser
public class CurrentUser implements Serializable {
//用户信息
private UserP user;
//用户的扩展信息
private UserInfoP userInfo;
//部门信息
private DeptP dept;
public UserP getUser() {
return user;
}
public void setUser(UserP user) {
this.user = user;
}
public UserInfoP getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfoP userInfo) {
this.userInfo = userInfo;
}
public DeptP getDept() {
return dept;
}
public void setDept(DeptP dept) {
this.dept = dept;
}
}
2.4.2 修改UserService
@Override
public CurrentUser findUserInfoDeptByUser(UserP user){
CurrentUser currentUser = new CurrentUser();
currentUser.setUser(user);// 设置用户基本信息
currentUser.setDept(deptPMapper.selectByPrimaryKey(user.getDeptId()));// 设置用户所属部门信息
currentUser.setUserInfo(userInfoPMapper.selectByPrimaryKey(user.getUserId()));// 设置用户详细信息
return currentUser;
}
2.4.3 修改realm
前边的配置文件已经全了
2.4.4 修改PageController
//跳转标题栏菜单
@RequestMapping("/homeAction_totitle")
public String homeAction_totitle(Model model){
Subject subject = SecurityUtils.getSubject();
CurrentUser currentUser = (CurrentUser) subject.getPrincipal();
model.addAttribute("currentUser",currentUser);
return "home/title";
}
2.4.5 修改title.jsp
<div id="userInfo" style="z-index:999;" onclick="HideLoginDiv()" title="点击关闭">
<img src="${ctx}/skin/default/images/title/avataronline.gif" border="0" style="margin-top:-1px;"/>
您好:<strong>${currentUser.userInfoP.name}</strong> |
您所属单位:
<strong>${currentUser.deptP.deptName}</strong>
<img src="${ctx}/skin/default/images/title/close.gif" border="0" />
</div>
2.5 退出
2.5.1 修改applicationContext-shiro.xml
<!--退出-->
/logout = logout