zoukankan      html  css  js  c++  java
  • shiro和spring和springmvc的集成

    maven配置文件:pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>cn.sx</groupId>
      <artifactId>shiro</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
     <properties>
            <spring.version>4.3.2.RELEASE</spring.version>
            <slf4j.version>1.6.6</slf4j.version>
            <log4j.version>1.2.17</log4j.version>
            <shiro.version>1.2.3</shiro.version>
        </properties>
        <dependencies>
            <!-- spring -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.7.4</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!-- log4j日志 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
    
            <!-- 连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.10</version>
            </dependency>
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.4</version>
            </dependency>
            <!-- mybatis和spring集成包 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.3.2</version>
            </dependency>
    
    <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>1.2.3</version>
            </dependency>
            <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache-core</artifactId>
                <version>2.6.0</version>
            </dependency>
    
            <!-- 加入servlet和jsp的依赖 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>2.2.1</version>
                <scope>provided</scope>
            </dependency>
    
    
            <!-- 引入shiro框架的依赖 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-quartz</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <!-- shiro和spring集成包 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <!-- MySQL数据库驱动依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.11</version>
            </dependency>
        </dependencies>
        <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.1</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
        </build>
      
    </project>


    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
     
      
         <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <init-param>
                <!-- 将spring管理的shiro框架生命周期交给Servlet -->
                <param-name>targetFilterLifecycle</param-name>
                <param-value>true</param-value>
            </init-param>
            <!-- 设置Spring容器中Filter对应Bean的id,可以不设,如果不设,必须保证当前Filter的name和Springbean的id值一致 -->
            <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>MVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring*.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>MVC</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    </web-app>


    log4j.properties

    log4j.rootLogger=INFO, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n

    shiro.xml

    #配置自定义realm
    #类似于 spring 的 <bean id="" class="">
    #自定义realm名称=自定义realm的全限定名
    customRealm=cn.sxt.CustomRealm
    
    #定义凭证器
    credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
    #算法
    credentialsMatcher.hashAlgorithmName=md5
    #散列次数
    credentialsMatcher.hashIterations=3
    #设置realm的凭证匹配器
    customRealm.credentialsMatcher=$credentialsMatcher
    
    #将自定义realm设置给SecurityManager的realm属性(类型Spring的依赖注入)
    securityManager.realms=$customRealm

    重写realm

    package cn.sxt;
    
    import java.util.Arrays;
    import java.util.List;
    
    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.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;
    
    public class CustomRealm extends AuthorizingRealm{
    
        /*
         * 认证方法,开发者在方法内部自定认证的规则
         * 
         * token :令牌,在 主体login 传递过来的
         * return AuthenticationInfo
         *         返回认证信息
         *         如果返回null,认为认证失败
         * 
         */
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            /*
             * 认证思路
             *     1.获取 token令牌的身份(账号)
             *  2.在当前类中注入 UserService,调用serice的根据账号去数据库查询用户方法
             *      service调用Mapper/Dao层的根据账号查询用户方法
             *    2.1 如果没有此用户,返回null,当前认证方法也返回null
             *    2.1 如果有此用户,把用户的密码和token的凭证(密码)进行匹配
             *        2.2.1,匹配不成功,当前认证方法也返回null
             *        2.2.1  匹配成功,创建一个AuthenticationInfo 认证信息对象,认证成功
             */
            //1.获取 token令牌的身份(账号)
            String username = (String) token.getPrincipal();
            /*User user=UserService.selectByUserName(username);
             * if(user !=null){
             *进一步比对
             * }
             * 
             * */
            //模拟数据库中的账号
            List<String> usernames = Arrays.asList("list","admin","hello");
            
            if(usernames.contains(username)) {
                //身份(账号)匹配成功,进一步匹配凭证(密码)
                System.out.println("账号匹配成功");
                //String password = user.getPassword();
                //(模拟数据库中的密码) abc + sen +散列三次后的密码
                String hashedCredentials="5585e2acfff82f34259391863c714c45";
                //数据库中的盐
                ByteSource credentialsSalt = ByteSource.Util.bytes("sen");
                //.创建返回认证信息的对象
                
                SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, hashedCredentials, credentialsSalt,this.getName());
                return simpleAuthenticationInfo;
            }
    
            return null;
        }
        /*
         * 授权方法
         */
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            
            Object username = principals.getPrimaryPrincipal();
            System.out.println(username);
            /*
             * 授权思路
             *     1.通过当前认证的身份去数据库里面查询出当前身份对应的角色--》对应的权限
             *         注入RoleService
             *         Role role = roleService.selectByPrimarykey(roleId); 
             *         role.permissionIds = 10,1,13,15,16,17,11,18,19,20,21,12,22,23,24,25
             *         List<String> permissionExpressions = permission.selectExpressionsByIds(权限id数组集合)
             *         例如
             *             user:lsit
             *             user:create 
             *             student:list
             *             等等
             *  2. 将当前身份 对应的角色对应的所有权限设置给Shiro 授权信息对象
             *  3. 程序运行shiro会自动判断当前身份是否有权限
             */
            //模拟数据库查询权限
            List<String> asList = Arrays.asList("user:list","user:insert");
            //创建一个授权信息对象
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            //将权限添加到shiro 授权信息对象:不能为空null
            simpleAuthorizationInfo.addStringPermissions(asList);
            System.out.println("CustomRealm.doGetAuthorizationInfo()");
            return simpleAuthorizationInfo;
        }
    
        
    
    }

    springmvc.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        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/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            ">
          <!-- shiro为集成springMvc 拦截异常 -->
        <bean
            class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
                    <!-- 没有权限异常跳转的页面
                        对应的页面在视图解析器下面
                        前缀+逻辑视图名称+后缀
                     -->
                    <prop key="org.apache.shiro.authz.UnauthorizedException">unauthorized</prop>
                </props>
            </property>
        </bean>    
            
            <context:component-scan base-package="cn.sxt"/>
            <mvc:annotation-driven/>
            <mvc:default-servlet-handler/>
            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/view/"/>
            <property name="suffix" value=".jsp"/>
            </bean>
            
    
            
            </beans>

    springshiro.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        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/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.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
            ">
    
        <aop:config proxy-target-class="true" />
        <!-- 开启aop,对代理类 -->
        <bean
            class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"></property>
        </bean>
    
    
    
    
        <!-- 配置Shiro框架的过滤器 -->
        <bean id="shiroFilter"
            class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            
            
            
            <!-- 注入安全管理器 -->
            <property name="securityManager" ref="securityManager" />
    
            <!-- 认证通过以后访问的页面 一般都是 后台首页 -->
            <property name="successUrl" value="/index.do" />
    
        <!-- 自定义Filter -->
            <property name="filters">
                <map>
                    <!-- 使用自定义的表单认证过滤器-->
                    <entry key="authc" value-ref="formAuthenticationFilter"></entry>
                </map>
            </property>
            
        
        
            <!-- 认证失败以后跳转的页面 /user/login.do -->
            <property name="loginUrl" value="/user/login.do" />
    
            <!-- 没有权限访问时候提示页面 -->
            <property name="unauthorizedUrl" value="/unauthorized.jsp"></property>
    
        
            
    
            <!-- shiro框架底层是多个过滤器,每个过滤都会有各自的职责 我们需要根据实际情况配置我们的过滤器链 配置规则 /资源 = 过滤器别名 
                /资源=过滤器别名 /** 所有资源 anon (org.apache.shiro.web.filter.authc.AnonymousFilter) 
                匿名访问过滤器,所有人都能方 authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter 
                表单认证过滤器 ,只有认证通过以后才能访问资源 logout org.apache.shiro.web.filter.authc.LogoutFilter 
                perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter 授权过滤器 
                语法 : /资源 = perms["权限"] user org.apache.shiro.web.filter.authc.UserFilter 
                设置记住我以后默认的访问页面 -->
            <property name="filterChainDefinitions">
    
                <value>
                    <!-- 过滤器代码从上到下执行,上面匹配,不会二次配置 -->
                    <!-- 登录页面匿名访问 -->
                    /login.jsp = anon
                    <!-- 各种静态资源 css js image图片 -->
                    /css/** = anon
                    /js/** = anon
                    /images/** = anon
                    <!-- 访问路径=需要什么权限访问 /index.do=perms[user:list] -->
    
                   <!-- 配置记住我访问的页面 -->
                    /index.do=user
    
                    <!-- 退出登录 -->
                    /user/logout.do = logout
                    <!-- 所有资源都需要认证才能访问 -->
                    /** = authc
    
    
    
    
                </value>
            </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>
            <!-- 注入Session会话管理器 -->
            <property name="sessionManager" ref="sessionManager"></property>
            <!-- 记住我 -->
            <property name="rememberMeManager" ref="rememberMeManager"></property>
        </bean>
    
    <!-- 自定义表单认证过滤器 -->
        <bean id="formAuthenticationFilter" class="cn.sxt.MyFormAuthenticationFilter">
            <!-- 设置表单提交的账号表单名称 -->
            <property name="usernameParam" value="name"/>
            <!-- 设置表单提交的账号表单名称 -->
            <property name="passwordParam" value="pwd"/>
            <!-- 设置表单提交的账号表单名称 -->
            <property name="rememberMeParam" value="rememberMe"/>
        </bean>
    
    
    
    
        <!-- 配置记住我 -->
        <bean id="rememberMeManager"
            class="org.apache.shiro.web.mgt.CookieRememberMeManager">
            <!-- 设置cookie信息 -->
            <property name="cookie">
                <bean class="org.apache.shiro.web.servlet.SimpleCookie">
                    <!-- 使用构造器设置cookie名称,保存到本地浏览器的key -->
                    <constructor-arg value="rememberMe"></constructor-arg>
                    <!-- 设置最大有效期 :单位秒 -->
                    <property name="maxAge" value="#{3600 * 24 * 3}" />
                </bean>
            </property>
        </bean>
    
    
    
    
    
        <!-- 配置Sesion会话管理器 -->
        <bean id="sessionManager"
            class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
            <!-- 设置session的失效时长,单位毫秒 -->
            <property name="globalSessionTimeout" value="#{1000*3600}"></property>
            <!-- 删除失效的session -->
            <property name="deleteInvalidSessions" value="true"></property>
        </bean>
    
        <!-- 配置缓存管理器 -->
        <bean id="cacheManager"
            class="org.apache.shiro.cache.ehcache.EhCacheManager">
            <property name="cacheManagerConfigFile"
                value="classpath:shiro-ehcache.xml" />
        </bean>
    
    
        <!-- 配置自定义CustomRealm -->
        <bean id="customRealm" class="cn.sxt.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="3"></property>
        </bean>
    
    
    
    
    
    </beans>

    shiro-ehcache.xml

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
        <!--diskStore:缓存数据持久化的目录 地址  -->
        <diskStore path="D:developehcache" />
        
        <defaultCache 
            maxElementsInMemory="1000" 
            maxElementsOnDisk="10000000"
            eternal="false" 
            overflowToDisk="false" 
            diskPersistent="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120" 
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        </defaultCache>
    </ehcache>


    自定义表单认证过滤器

    package cn.sxt;
    
    import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
    
    public class MyFormAuthenticationFilter extends FormAuthenticationFilter{
    
    }

    登录后台代码

    package cn.sxt.contorller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class IndexController {
    
        @RequestMapping("/index")
        public String index() {
            return "index";
            
        }
    }
    package cn.sxt.contorller;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("/user")
    
    public class UserContorller {
        
        
        @Scope("request")
        @RequestMapping("/list")
        @RequiresPermissions("user:list")
        public String list() {
            return "list";
            
        } 
    
        @RequestMapping("/login")
        public String login(HttpServletRequest request,Model m) {
        //获取认证失败的错误信息,在Shiro框架的 FormAuthenticationFilter 过滤器中共享
        // 共享的属性名称  shiroLoginFailure
        // 共享的 shiro 异常的字节码    
            String shiroLoginFailure = (String) request.getAttribute("shiroLoginFailure");
            
        
            if(shiroLoginFailure !=null) {
    
                if(UnknownAccountException.class.getName().equals(shiroLoginFailure)) {
                    m.addAttribute("erroyMsg", "亲。账号不存在");
                }else if(IncorrectCredentialsException.class.getName().equals(shiroLoginFailure)) {
                    m.addAttribute("erroyMsg", "亲。密码错误");
                }    
            }
            
            
            return "forward:/login.jsp";
            
        }
        @RequestMapping("/logout")
        public String logout() {
            //使用shiro之前,清除Cookie和Session
            
            return "redirect:/login.jsp";
            
        }
    }
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h3>登录页面</h3>
    <span style="color: red">${erroyMsg}</span>
    <form action="${pageContext.request.contextPath}/user/login.do" method="post">
        账号:<input name="name"/><br>
        密码:<input name="pwd" type="password"/><br>
        记住我:<input type="checkbox" name="rememberMe"><br>
        <button type="submit">登录</button>    
    </form>
    </body>
    </html>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    亲,没有权限访问
    </body>
    </html>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     
        <!-- 引入shiro标签 -->
    <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    
    后台首页<br>
    
    <%-- 
        判断当前认证的身份是否拥有指定的权限
        如果有权限,执行标签体中的代码,如果没有权限,不执行
        <shiro:hasPermission name="user:list">
            标签体
        </shiro:hasPermission>
    
     --%>
    
    <shiro:hasPermission name="user:list">
        <a href="${pageContext.request.contextPath}/user/list.do">用户列表</a><br>
    </shiro:hasPermission>
    
    
    欢迎,<shiro:principal></shiro:principal><a style="float: right;" href="${pageContext.request.contextPath}/user/logout.do">退出登录</a>
    </body>
    </html>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    用户列表
    </body>
    </html>
  • 相关阅读:
    Btrace入门到熟练小工完全指南
    mysqldump常用于MySQL数据库逻辑备份
    thrift总结
    十大技巧优化Android App性能
    Google 发布 Android 性能优化典范
    Android性能优化之一:ViewStub
    Android实战技巧:ViewStub的应用
    安装andriod studio时出现Internal error. Please report to https://code.google.com/p/an
    Android Service的生命周期
    Android 70道面试题汇总不再愁面试
  • 原文地址:https://www.cnblogs.com/406070989senlin/p/11228816.html
Copyright © 2011-2022 走看看