相关的配置在这里不多说了,直接贴代码。
很多东西都是看<架构探险> 阿里巴巴架构师黄勇的书(轻量级企业开发smart框架),一点一点整合的,顺便推荐一下。
第一步:web.xml配置
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 防止spring内存溢出监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- shiro的filter -->
<!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 设置true由servlet容器控制filter的生命周期 -->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean-->
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</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:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- CXF -->
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/common/403.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/common/403.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/common/404.jsp</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/common/403.jsp</location>
</error-page>
<!-- 配置session超时时间,单位分钟 -->
<!-- <session-config>
<session-timeout>15</session-timeout>
</session-config> -->
</web-app>
第二步:spring相关配置
applicationContext-advice.xml
<!-- 配置前置通知 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="beforeAdvice" class="com.zh.ssm.aop.AopAdvice"></bean>
</beans>
@Aspect
public class AopAdvice {
@Before("execution(* com.zh.ssm.service.impl.*.*(..))")
public void before(JoinPoint point){
/*System.out.println("【"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"】:");
System.out.println("@Before:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs()));
System.out.println("@Before:被织入的目标对象为:" + point.getTarget());*/
}
@After("execution(* com.zh.ssm.service.impl.*.*(..))")
public void releaseResource(JoinPoint point) {
/*System.out.println("@After:模拟释放资源...");
System.out.println("@After:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@After:参数为:" + Arrays.toString(point.getArgs()));
System.out.println("@After:被织入的目标对象为:" + point.getTarget());*/
}
applicationContext-cxf.xml
<context:component-scan base-package="com.zh.ssm.ws.soap_cxf.impl"/>
<jaxws:endpoint id="helloService" implementor="#helloServiceImpl" address="/soap/hello" />
@WebService
public interface HelloService {
String say(String name);
}
@WebService
@Component
public class HelloServiceImpl implements HelloService {
public String say(String name) {
return "hello:"+name;
}
}
测试cxf
public class CxfMain {
public static void main(String[] args) {
JaxWsProxyFactoryBean factory=new JaxWsProxyFactoryBean();
factory.setAddress("http://localhost:8080/ssm/ws/soap/hello");
factory.setServiceClass(HelloService.class);
HelloService helloService=factory.create(HelloService.class);
String result=helloService.say("world");
System.out.println(result);
}
applicationContext-dao.xml
<!-- 分散配置 加载jdb连接属性-->
<context:property-placeholder location="classpath:config.properties"/>
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/zh/ssm/model/*.xml" />
<property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml"/>
</bean>
<!-- mapper扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zh.ssm.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
applicationContext-service.xml
<context:component-scan base-package="com.zh.ssm.service.impl"/>
applicationContext-shiro.xml(注:关于shiro也是入门级别的,只是保证权限是通畅的。其他的小弟也没怎么研究)
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- 自定义filter配置 -->
<property name="filters">
<map>
<!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property>
<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 匿名可以访问的 -->
/index.jsp=anon
/**/uicsses/**=anon
/**/uiplugins/**=anon
/ws/soap/hello=anon
/ws=anon
/user/tologin.action=anon
/user/dologin.action=anon
/user/register.action=anon
/user/logout.action=anon
/user/getCode.action=anon
<!-- 认证通过才能访问 -->
/user/getAllUser.action=authc
/**=authc
</value>
</property>
</bean>
<!-- securityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 自定义realm -->
<property name="realm" ref="customRealm" />
<!-- 注入缓存管理器 -->
<!-- <property name="cacheManager" ref="cacheManager"/> -->
<!-- 注入session管理器 -->
<!-- <property name="sessionManager" ref="sessionManager" /> -->
<!-- 记住我 -->
<!-- <property name="rememberMeManager" ref="rememberMeManager"/> -->
</bean>
<!-- realm -->
<bean id="customRealm" class="com.zh.ssm.shiro.realm.CustomRealm">
</bean>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session的失效时长,单位毫秒 -->
<property name="globalSessionTimeout" value="600000"/>
<!-- 删除失效的session -->
<property name="deleteInvalidSessions" value="true"/>
</bean>
<!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter" class="com.zh.ssm.shiro.realm.CustomFormAuthenticationFilter">
<!-- 表单中账号的input名称 -->
<property name="usernameParam" value="name" />
<!-- 表单中密码的input名称 -->
<property name="passwordParam" value="pwd" />
<!-- 记住我input的名称 -->
<property name="rememberMeParam" value="rememberMe"/>
</bean>
<!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie" ref="rememberMeCookie" />
</bean>
<!-- 记住我cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- rememberMe是cookie的名字 -->
<constructor-arg value="rememberMe" />
<!-- 记住我cookie生效时间30天 -->
<property name="maxAge" value="2592000" />
</bean>
自定义realm:相当于配置一个数据源
package com.zh.ssm.shiro.realm;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Resource;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import com.zh.ssm.service.ShiroServiceI;
public class CustomRealm extends AuthorizingRealm {
@Resource ShiroServiceI shiroService;
//用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
<span style="white-space:pre"> </span>if (principals == null) {
throw new AuthorizationException("parameter principals is null");
}
String username = (String) super.getAvailablePrincipal(principals);
try {
Set<String> roleNameSet =shiroService.getRoleNameSet(username);
Set<String> permissionNameSet = new HashSet<String>();
if (roleNameSet != null && roleNameSet.size() > 0) {
for (String roleName : roleNameSet) {
Set<String> currentPermissionNameSet = shiroService.getPermissionNameSet(roleName);
permissionNameSet.addAll(currentPermissionNameSet);
}
}else{
roleNameSet.add("没有相关权限");
}
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(roleNameSet);
authorizationInfo.setStringPermissions(permissionNameSet);
return authorizationInfo;
<span style="white-space:pre"> </span>} catch (Exception e) {
<span style="white-space:pre"> </span>throw new RuntimeException("查询失败");
<span style="white-space:pre"> </span>}
}
//用于认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if (token == null) {
throw new AuthenticationException("parameter token is null");
}
String username = ((UsernamePasswordToken) token).getUsername();
try {
String password = shiroService.getPwd(username);
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo();
authenticationInfo.setPrincipals(new SimplePrincipalCollection(username, super.getName()));
authenticationInfo.setCredentials(password);
return authenticationInfo;
} catch (Exception e) {
throw new RuntimeException("查询失败");
}
}
}
登录和注销:
package com.zh.ssm.utils.util.shiro;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
public final class ShiroHelper {
private static final Logger logger = Logger.getLogger(ShiroHelper.class);
public static void login(String name,String pwd){
Subject currentUser=SecurityUtils.getSubject();
if(currentUser!=null){
UsernamePasswordToken token=new UsernamePasswordToken(name,pwd);
try {
currentUser.login(token);
} catch (AuthenticationException e) {
logger.error("login failure");
throw new AuthenticationException("e");
}
}
}
public static void logout(){
Subject currentUser=SecurityUtils.getSubject();
currentUser.logout();
}
}
页面测试:
<shiro:guest>
<form action="dologin.action" method="post">
<table id="main_table">
<tr><td colspan="2" style="font-size: 18px;text-align: center;">登录 <a href="../index.jsp">新用户注册</a></td></tr>
<tr><td class="main_table_td">用户名:</td><td><input style="margin-left: -150px" type="text" name="name" required="true"></td></tr>
<tr><td class="main_table_td">密码:</td><td><input style="margin-left: -150px" type="password" name="pwd" required="true"></td></tr>
<tr>
<td class="main_table_td">验证码:</td>
<td><input style="margin-left: -17px" type="text" name="randomcode" required="true" /><img src="getCode.action" id="image"> <input type="button" value="换一张" οnclick="_hyz()"></td>
</tr>
<tr><td colspan="2" align="center" >
<input type="submit" value="登录" class="btn btn-success btn-sm"/>
<input type="reset" value="重置" class="btn btn-success btn-sm" />
</tr>
</table>
</form>
</shiro:guest>
<shiro:user>
<p>身份:<shiro:principal/></p>
<c:redirect url="getAllUser.action"></c:redirect>
</shiro:user>
<body>
<shiro:hasRole name="没有相关权限">
Sorry,没有相关权限不能访问该页面
</shiro:hasRole>
<shiro:hasRole name="管理员">
<shiro:hasPermission name="xxx"></shiro:hasPermission>
<%-- <shiro:lacksRole name="..."></shiro:lacksRole> --%>
<%-- <shiro:lacksPermission name="..."></shiro:lacksPermission> --%>
<table border="1" width="800" style="margin:50px auto;">
<tr align="center">
<th>id</th>
<th>用户名</th>
<th>密码</th>
<th>操作</th>
</tr>
<c:forEach items="${users}" var="user">
<tr align="center">
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.pwd}</td>
<td><a href="deleteUser.action?id=${user.id}">删除</a></td>
</tr>
</c:forEach>
</table>
</shiro:hasRole>
</body>
applicationContext-transaction.xml
<!-- 配置事务管理器 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 通知 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<!--事物传播性 -->
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<!--SUPPORTS 支持事物 -->
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="transactionAdvice" pointcut="execution(* com.zh.ssm.service.impl.*.*(..))"/>
</aop:config>
springmvc.xml
<!--扫描控制器 handler -->
<context:component-scan base-package="com.zh.ssm.controller"/>
<!--注解映射器 -->
<!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置
mvc:annotation-driven默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
实际开发时使用mvc:annotation-driven
-->
<mvc:annotation-driven />
<!-- 视图解析器 解析jsp解析,默认使用jstl标签,classpath下的得有jstl的包 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置jsp路径的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 配置jsp路径的后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 定义统一异常处理器 -->
<bean class="com.zh.ssm.exception.CustomExceptionResolver"></bean>
<!--拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 用户认证拦截 -->
<mvc:mapping path="/**" />
<bean class="com.zh.ssm.controller.Interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 用户授权拦截 -->
<mvc:mapping path="/**" />
<bean class="com.zh.ssm.controller.Interceptor.PermissionInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
第三步:mybatis相关配置
sqlMapConfig.xml<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 别名 -->
<typeAliases>
<!-- 批量扫描别名 -->
<package name="com.zh.ssm.model"/>
</typeAliases>
</configuration>
第四步:注入调用
@Controller("userController")
@RequestMapping("/user")
public class UserController {
private static final Logger logger = Logger.getLogger(UserController.class);
@Resource private UserServiceI userService;
/**
* 注册成功到达首页
* @param name
* @param pwd
* @return
*/
public interface ShiroServiceI{
String getPwd(String name)throws Exception;
Set<String> getRoleNameSet(String name)throws Exception;
Set<String> getPermissionNameSet(String rolename)throws Exception;
}
<pre name="code" class="java">package com.zh.ssm.service.impl;
import java.util.Set;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.zh.ssm.dao.UserMapper;
import com.zh.ssm.service.ShiroServiceI;
@Service("shiroServcie")
public class ShiroServiceImpl implements ShiroServiceI {
@Resource private UserMapper userMapper;
@Override
public String getPwd(String username) throws Exception {
return userMapper.getPwd(username);
}
@Override
public Set<String> getRoleNameSet(String username) throws Exception {
return userMapper.getRoleNameSet(username);
}
@Override
public Set<String> getPermissionNameSet(String rolename) throws Exception {
return userMapper.getPermissionNameSet(rolename);
}
}
public interface PermissionMapper {
int deleteByPrimaryKey(String id);
int insert(Permission record);
int insertSelective(Permission record);
Permission selectByPrimaryKey(String id);
int updateByPrimaryKeySelective(Permission record);
int updateByPrimaryKey(Permission record);
}
</pre><pre name="code" class="java"><select id="getPwd" resultType="String" >
select pwd from user where name=#{name}
</select>
<select id="getRoleNameSet" resultType="String">
select r.rolename from `user` u, role r ,userrole ur where u.id=ur.userid and r.id=ur.roleid and u.`name`=#{name}
</select>
<select id="getPermissionNameSet" resultType="String">
select p.permissionname from permission p, role r, rolepermission rp where r.id=rp.roleid and p.id=rp.permissionid and r.rolename=#{rolename}
</select>
<pre name="code" class="java">//shiro
String getPwd(@Param(value="name")String username)throws Exception;
Set<String> getRoleNameSet(@Param(value="name")String username)throws Exception;
Set<String> getPermissionNameSet(@Param(value="rolename")String rolename)throws Exception;
........不足之处请各位见谅。