欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SSM 小demo的盲点总结

程序员文章站 2022-04-26 17:53:27
日期Date和String之间的转换: 1. 全局转换器(推荐使用) 1. 创建类实现Converter接口,实现Convert方法 public class StringToDateConvert implements Converter { @Override public Date conve ......

日期date和string之间的转换:

1. 全局转换器(推荐使用)
    1. 创建类实现converter接口,实现convert方法
        public class stringtodateconvert implements converter<string, date> {
            @override
            public date convert(string resource) {
                if(resource == null){
                    throw new runtimeexception("请输入值");
                }
                dateformat df = new simpledateformat("yyyy-mm-dd hh:mm");
                try {
                    date parse = df.parse(resource);
                    return parse;
                } catch (parseexception e) {
                    throw new runtimeexception("数据格式转换异常");
                }
            }
        }
    2. 在springmvc的配置文件中进行配置转换器
         <!--配置自定义日期转换器-->
        <bean id="conversionservice" class="org.springframework.context.support.conversionservicefactorybean">
            <property name="converters">
                <set>
                    <bean class="cn.wzlove.utils.stringtodateconvert"/>
                </set>
            </property>
        </bean>
        <!--开启mvc注解驱动(加载处理器映射器和处理器适配器)-->
        <mvc:annotation-driven conversion-service="conversionservice">
        </mvc:annotation-driven>
        
2. 属性转换器
    使用注解进行转换:
    @datetimeformat(pattern = "yyyy-mm-dd hh:mm")
    private date departuretime;
    

对于日期在页面的展示(get方法需要注意)

对于日期在页面上的展示考虑使用字符串,多创建一个string属性,在前台展示的时候使用这个字符串属性,记得转换类型就好.

实体类:
     private date departuretime;
     private string departuretimestr;
     
     public string getdeparturetimestr() {
        if(departuretime != null){
            departuretimestr = datefromatutils.date2string(departuretime,"yyyy-mm-dd hh:mm");
        }
        return departuretimestr;
    }
datefromatutils:
    public class datefromatutils {
        /**
         * 日期转时间
         * @param date
         * @param patt
         * @return
         */
        public static string date2string(date date, string patt){
            simpledateformat sdf = new simpledateformat(patt);
            string format = sdf.format(date);
            return format;
        }
    
    
        /**
         * 字符串转日期
         * @param time
         * @param patt
         * @return
         */
        public static date string2date(string time, string patt){
            simpledateformat sdf = new simpledateformat(patt);
            try {
                date date = sdf.parse(time);
                return date;
            } catch (parseexception e) {
                e.printstacktrace();
                throw new runtimeexception("日期转换异常");
            }
        }
    }

对于特殊的标记属性在页面的展示(get方法需要注意)

与日期类似,创建额外表示的字段
     /**
     * 状态 0 关闭 1 开启
     */
    private integer productstatus;

    /**
     * 对状态的字符串描述
     */
    private string productstatusstr;
    
     public string getproductstatusstr() {
        if(null != productstatus){
            if(productstatus == 0){
                productstatusstr = "关闭";
            } else if(productstatus == 1){
                productstatusstr = "开启";
            }
        }
        return productstatusstr;
    }
    

mybatis的一对一和多对多的回顾:

一对一:
    @select("select * from orders")
    @results({
            @result(id = true,property = "id", column = "id"),
            @result(property = "ordernum",column = "ordernum"),
            @result(property = "ordertime",column = "ordertime"),
            @result(property = "orderstatus",column = "orderstatus"),
            @result(property = "peoplecount",column = "peoplecount"),
            @result(property = "paytype",column = "paytype"),
            @result(property = "orderdesc",column = "orderdesc"),
            @result(property = "product",column = "productid",javatype = product.class,
            one = @one(select = "cn.wzlove.mapper.productmapper.findproductbyid"))
    })
多对多:
    @select("select * from orders where id = #{ordersid}")
    @results({
            @result(id = true,property = "id", column = "id"),
            @result(property = "ordernum",column = "ordernum"),
            @result(property = "ordertime",column = "ordertime"),
            @result(property = "orderstatus",column = "orderstatus"),
            @result(property = "peoplecount",column = "peoplecount"),
            @result(property = "paytype",column = "paytype"),
            @result(property = "orderdesc",column = "orderdesc"),
            @result(property = "product",column = "productid",javatype = product.class,
                    one = @one(select = "cn.wzlove.mapper.productmapper.findproductbyid")),
            @result(property = "member",column = "memberid",javatype = member.class,
                    one = @one(select = "cn.wzlove.mapper.membermapper.findmemberbyid")),
            @result(property = "travellers",column = "id",javatype = java.util.list.class,
                    many = @many(select = "cn.wzlove.mapper.travellermapper.findtravelbyorderid"))
    })
    

pagehelper的使用:

1. 导入依赖
    <dependency>
        <groupid>com.github.pagehelper</groupid>
        <artifactid>pagehelper</artifactid>
        <version>5.1.2</version>
    </dependency>
2. 进行配置
     <!--配置sqlsessionfactory-->
    <bean id="sqlsessionfactory" class="org.mybatis.spring.sqlsessionfactorybean">
        <property name="datasource" ref="datasource"/>
        <property name="typealiasespackage" value="cn.wzlove.domain"/>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.pageinterceptor">
                    <property name="properties">
                        <props>
                            <prop key="helperdialect">oracle</prop>
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>
    </bean>
3. 进行使用
     @requestmapping("findall.do")
    public modelandview findordersall(@requestparam(name = "page",required = true,defaultvalue = "1") integer page,
                                      @requestparam(name = "size",required = true,defaultvalue = "4") integer size){
        modelandview mv = new modelandview();
        pagehelper.startpage(page,size);
        list<orders> allorders = ordersservice.findallorders();
        pageinfo<orders> pageinfo = new pageinfo<>(allorders);
        mv.addobject("pageinfo",pageinfo);
        mv.setviewname("orders-list");
        return mv;
    }
4. 对于pageinfo考虑查看源码看看封装的分页信息,列出常用的
     //当前页
    private int pagenum;
    //每页的数量
    private int pagesize;
    //当前页的数量
    private int size;

    //由于startrow和endrow不常用,这里说个具体的用法
    //可以在页面中"显示startrow到endrow 共size条数据"

    //当前页面第一个元素在数据库中的行号
    private int startrow;
    //当前页面最后一个元素在数据库中的行号
    private int endrow;
    //总记录数
    private long total;
    //总页数
    private int pages;
    //结果集
    private list<t> list;

    //前一页
    private int prepage;
    //下一页
    private int nextpage;
    

权限的管理(srping security的使用)

1. srping security的使用: 安全框架(认证和授权)
    1. 导入依赖
        spring-security-web
        spring-security-config
    2. web.xml配置过滤器
        contextloaderlistener----------> 加载spring-security.xml的配置文件
        delegatingfilterproxt----------> 委托过滤器代理类-----> springsecurityfilterchain(名字不能变)
    3. spring-security核心配置文件的配置
        1. 哪些资源不登录也能访问,也就是过滤
            <security:http pattern="" security="none" >
        2. 认证管理器
            <security:authentication-manager>
        3. 配置拦截规则
             <security:http auto-config="true" use-expressions="false">
代码如下:
    2. web.xml的配置:
        <filter>
            <filter-name>springsecurityfilterchain</filter-name>
            <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>springsecurityfilterchain</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        
        <context-param>
            <param-name>contextconfiglocation</param-name>
            <!--
                classpath和classpath*的区别
                    前者表示当前工程的类路径下加载配置文件
                    后者表示从当前工程的类路径及jar包的类路径下加载
            -->
            <param-value>
                classpath*:applicationcontext.xml,
                classpath*:spring-security.xml
            </param-value>
        </context-param>
    3. spring-security.xml的配置:
        <?xml version="1.0" encoding="utf-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:security="http://www.springframework.org/schema/security"
               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/security
            http://www.springframework.org/schema/security/spring-security.xsd">
        
            <!-- 配置不拦截的资源 -->
            <security:http pattern="/login.jsp" security="none"/>
            <security:http pattern="/failer.jsp" security="none"/>
            <security:http pattern="/css/**" security="none"/>
            <security:http pattern="/img/**" security="none"/>
            <security:http pattern="/plugins/**" security="none"/>
        
            <!--
                配置具体的规则
                auto-config="true"  不用自己编写登录的页面,框架提供默认登录页面
                use-expressions="false" 是否使用spel表达式(没学习过)
            -->
            <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有role_user的角色" -->
            <security:http auto-config="true" use-expressions="false">
                <security:intercept-url pattern="/**" access="role_user,role_admin"/>
        
                <!-- 定义跳转的具体的页面 -->
                <security:form-login
                        login-page="/login.jsp"
                        login-processing-url="/login"
                        default-target-url="/index.jsp"
                        authentication-failure-url="/failer.jsp"
                        authentication-success-forward-url="/pages/main.jsp"
                />
        
                <!-- 关闭跨域请求 -->
                <security:csrf disabled="true"/>
        
                <!-- 退出 -->
                <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp" />
        
            </security:http>
        
            <!-- 切换成数据库中的用户名和密码 -->
            <security:authentication-manager>
                <security:authentication-provider user-service-ref="userservice">
                    <!-- 配置加密的方式(开始的时候由于密码没有加密,所以将这个应该先注释掉,等到密码加密了再放开) -->
                    <security:password-encoder ref="passwordencoder"/>
                </security:authentication-provider>
            </security:authentication-manager>
        
            <!-- 配置加密类 -->
            <bean id="passwordencoder" class="org.springframework.security.crypto.bcrypt.bcryptpasswordencoder"/>
        
            <!-- 提供了入门的方式,在内存中存入用户名和密码
            <security:authentication-manager>
                <security:authentication-provider>
                    <security:user-service>
                        <security:user name="admin" password="{noop}admin" authorities="role_user"/>
                    </security:user-service>
                </security:authentication-provider>
            </security:authentication-manager>
            -->
            <!--如果密码没有加密,则密码前需要添加{noop}-->
        </beans>
        

spring security的权限控制

服务器的权限控制
1. jsr250注解配置
    1. 在pom.xml中引入依赖
        <dependency>
            <groupid>javax.annotation</groupid>
            <artifactid>jsr250-api</artifactid>
            <version>1.0</version>
        </dependency>
    2. 在spring-security.xml的配置文件中开启注解开关
         <security:global-method-security  jsr250-annotations="enabled"></security:global-method-security>
    3. 在方法上使用注解(一般在controller注解上)
        @rolesallowed({"admin","user"}) ====> 必须有admin或者user角色才可以访问此方法
        @permitall  ====> 允许所有的角色都可以访问
        @denyall  ====> 所有的角色都不可以访问
         
2. 使用@secured注解
    1. 在spring-security.xml的配置文件中开启注解开关
        <security:global-method-security secured-annotations="enabled"></security:global-method-security>
    2. 使用注解
        @secured("role_admin") ====> 拥有admin角色的用户可以访问,必须要有role_
3. 基于表达式的
    1. 在配置文件中开启注解开关
        <security:global-method-security pre-post-annotations="enabled" ></security:global-method-security>
    2. @preauthorize("hasrole('role_admin')") ====> 如果表达式返回true,可以访问该方法,由于使用了spel表达式,所以配置文件需要更改(在原来的基础上,修改use-expressions和access):
        <security:http auto-config="true" use-expressions="true">
    <security:intercept-url pattern="/**" access="hasanyrole('role_user','role_admin')"/>
    
     @preauthorize("authentication.principal.username == 'wzlove'")表示只有wzlove用户可以访问
前端的权限控制
1. 在pom.xml中引入依赖
     <dependency>
        <groupid>org.springframework.security</groupid>
        <artifactid>spring-security-taglibs</artifactid>
        <version>${spring.security.version}</version>
    </dependency>
2. 在jsp页面引入标签库:
    <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
3. 标签的使用:
    1. 获取当前登录的用户名
        <security:authentication property="principal.username"/>
    2. 根据权限隐藏标签(拥有admin角色才可以显示该标签)
        <security:authorize access="hasrole('admin')">
            <li id="system-setting"><a
                href="${pagecontext.request.contextpath}/user/findall"> <i
                    class="fa fa-circle-o"></i> 用户管理
            </a></li>
        </security:authorize>
        

springaop的日志记录控制(把数据存放在数据库中)

1. 创建数据库的表结构:
    create table syslog(
        id varchar2(32) default sys_guid() primary key,
        visittime timestamp,
        username varchar2(50),
        ip varchar2(30),
        url varchar2(50),
        executiontime int,
        method varchar2(200)
    )
2. 创建日志实体:
    public class syslog {

        /**
         * 主键uuid
         */
        private string id;
        /**
         * 访问时间
         */
        private date visittime;
        /**
         * 访问时间前台展示
         */
        private string visittimestr;
        /**
         * 操作者
         */
        private string username;
        /**
         * 操作者ip
         */
        private string ip;
        /**
         * 操作的url
         */
        private string url;
        /**
         * 执行的时长
         */
        private long executiontime;
        /**
         * 访问方法
         */
        private string method;
        
        setter和getter
    }
4. 创建mapper:
    @mapper
    public interface syslogmapper {
    
    
        @insert("insert into syslog(visittime,username,ip,url,executiontime,method) values(#{visittime},#{username},#{ip},#{url},#{executiontime},#{method})")
        void savesyslog(syslog syslog);
    
        @select("select * from syslog")
        list<syslog> findall();
    
    }
5. aop控制:
    @component
    @aspect
    public class logaop {
    
        @autowired
        private httpservletrequest request;
    
        @autowired
        private syslogservice syslogservice;
    
        @around("execution(* cn.wzlove.controller.*.*(..))")
        public object around(proceedingjoinpoint pjp) throws throwable {
    
            object proceed = null;
            // 访问方法(分别获取类和方法,然后进行拼接)
            string classname = pjp.gettarget().getclass().getname();
            string methodname = pjp.getsignature().getname();
            // 忽略日志本身的controller
            if("cn.wzlove.controller.syslogcontroller".equals(classname)){
                // 获取参数
                object[] args = pjp.getargs();
                // 执行原始方法(放行)
                proceed = pjp.proceed(args);
            } else{
                // 封装syslog,获取syslog的属性
                // 访问时间
                date visitdate = new date();
                // 操作者
                string loginname = securitycontextholder.getcontext().getauthentication().getname();
                // 操作者ip
                string remoteaddr = request.getremoteaddr();
                // 操作的url
                string requesturi = request.getrequesturi();
    
    
    
                // 执行时长
                long starttime = system.currenttimemillis();
                // 获取参数
                object[] args = pjp.getargs();
                // 执行原始方法(放行)
                proceed = pjp.proceed(args);
    
                // 结束时间
                long endtime = system.currenttimemillis();
                long executetime = endtime - starttime;
    
                // 封装syslog
                syslog syslog = new syslog();
                syslog.setip(remoteaddr);
                syslog.setexecutiontime(executetime);
                syslog.setmethod(classname+"."+methodname);
                syslog.setusername(loginname);
                syslog.setvisittime(visitdate);
                syslog.seturl(requesturi);
    
                // 进行插入操作
                syslogservice.savesyslog(syslog);
            }
    
    
    
            return proceed;
        }
    
    
    }
6. 日志的controller
    @controller
    @requestmapping("syslog")
    public class syslogcontroller {
    
    
        @autowired
        private syslogservice syslogservice;
    
        @requestmapping("findall")
        public modelandview findall(){
            modelandview mv = new modelandview();
            list<syslog> all = syslogservice.findall();
            mv.addobject("syslogs",all);
            mv.setviewname("syslog-list");
            return mv;
        }
    
    }