zoukankan      html  css  js  c++  java
  • 如何写一个SSH项目(三)如何进行交互的

    下面以登录为例子,展示从前台到后端的一整套流程并进行分析.

    首先介绍一下我的SSH的分层结构

    • action和service一起是业务逻辑层          action层调用service层
    • dao层是数据访问层,也叫做持久层          里面是对数据库的操作
    • model是数据库表对应的实体类              我把每个对应的hibernate的配置也写在了这里
    • conf包 这里放的是细分的spring和struts的配置文件  一般是一个业务模块一个配置文件 
    • interceptor包  是我自己定义的拦截器     很多时候struts自带拦截器并不能达到我们的要求
    • common包     是自己定义的共用的方法   比如说 定义的常量  工具类

    大体的分层就清晰了.

    那么我们就上干货吧,直接上代码和分析. 这里只讲流程,不对调用的方法进行涉及.

    1.首先是登录界面 logon.jsp

    <s:form method="post" target="_parent" namespace="/login" action="loginAction" onsubmit="return checkInfor()">
                <div class="login_left">
                    <h3 class="login_h3">欢迎登录图友网</h3>
                    <div class="login_sr">
                        用户名: <!-- <input type="text" class="login_inputYhm"> -->
                        <s:textfield cssClass="login_inputYhm" id="loginName" name="loginName" onfocus="selectText(this)" />
                    </div>
                    <div class="login_sr">
                        密码: &nbsp;&nbsp;&nbsp;<!-- <input type="password" class="login_inputMm"> -->
                        <s:password showPassword="true" cssClass="login_inputMm" id="password" name="password" onfocus="selectText(this)" />
                    </div>
                    <div class="login_sr">
                        <div style="float:left">验证码:</div>
                        &nbsp;&nbsp; <!-- <input type="text" name="validateCode" maxlength="4" class="login_inputYzm" style="float:left;"> -->
                            <s:textfield maxLength="4" cssClass="login_inputYzm" style="float:left;" name="validateCode" id="validateCode" value="验证码" onfocus="selectText(this)" />
                        <div class="login_inputYzmPic" style="float:left">
                                <img src="<%=basePath%>login/loginAction!findValidateCode" id="validateImage" onclick="refresh()" title="看不清,换一张">
                            </div>
                            <%-- <span class="login_inputYzmH" onclick="changeCode()">换一张</span> --%>
                    </div>
                    <div>
    
                        <!-- <button type="submit" value="登录" style="height:30px;50px">登录</button> -->
                        <s:submit type="button" cssStyle="height:30px;50px" method="login" value="登录"></s:submit>
                    </div>
                    <div class="login_zcymm">
                        <a href="<%=basePath%>picturefriend/login/register.jsp">注册帐号</a>
                    </div>
                </div>

    点击提交的时候,web.xml中我们配置的struts拦截器会对请求进行拦截,去对应的struts配置文件寻找对应的action处理类,这里可以看到命名空间是/login action是loginAction

    method是login.然后会去寻找/login对应的包  这个寻找顺序请自己看我之前的文章

    2.struts-login.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" 
    "http://struts.apache.org/dtds/struts2.1.dtd">
    <struts>
        <package name="login" namespace="/login" extends="common">
           <!-- 这里的common包是在strtus.xml中配置的 就是我们之前自定义的拦截器-->
    <action name="loginAction" class="loginAction"> <!-- stream 直接向响应中发送原始数据 通常在用户下载时使用 contentType指定流的类型 contentLength以byte 计算流的长度, contentDisposition指定文件的位置,通常为 filename=”文件的位置”, --> <result name="getValidateCode" type="stream"> <param name="inputName">imageInputStream</param> <param name="contentType">image/jpeg</param> </result> <!-- <result name="result1" type="dispatcher">/picturefriend/main/userIndex.jsp</result> <result name="result2" type="dispatcher">/picturefriend/main/userIndex.jsp</result> --> <result name="userSuccess" type="dispatcher">/picturefriend/main/userIndex.jsp</result> <result name="adminSuccess" type="dispatcher">/picturefriend/main/adminIndex.jsp</result> <result name="input" type="dispatcher">/picturefriend/login/login.jsp</result> <result name="logout" type="redirect">/picturefriend/login/login.jsp</result> </action> </package> </struts>

    找到了 /login包 然后寻找此包下名为loginAction的action.看到没每一个actionn都有几个result,result是根据业务逻辑返回的字符串去寻找对应的视图

    可是为什么这里的class不是一个长长的全名路径是一个字符串呢?  这是因为我们在struts.xml配置了将bean交给了spring去处理,所以我们要根据这个loginAction去Spring找了.

    3.applicationContext-action.xml

        <bean id="loginAction" class="com.chinasoft.action.login.LoginAction"
            scope="prototype">
            <property name="loginService" ref="loginService"></property>
            <property name="productSortService" ref="productSortService"></property>
        </bean>

    这里的id就是我们的loginAction class是业务逻辑处理类, property是action处理类的属性,也就是说此action将会用到这两个service类.ref是bean的id.

    4.com.chinasoft.action.login.LoginAction.java

    因为我们的jsp上对应的方法是login 所以我们只需在业务逻辑类中关注login方法即可.

    private LoginService loginService; 
    public
    String login() { if (!getSession().get(Constant.SESSION_VALIDATE).toString() .equalsIgnoreCase(validateCode)) { getRequest().put("state", "2"); return INPUT; } //根据输入用户,查询User表 SysUser user = loginService.findUserByLoginName(loginName); if (user != null) {// 根据用户名可以检索到用户信息 System.out.println("用户表中有该用户!"); return judgeUser(user); } else {// 用户表中没有输入的帐号 return judgeAdmin(); } }

    此处我们看到会调用loginService,循环上面的步骤
    5.ApplicationContext-service.xml

    <bean id="loginService" class="com.chinasoft.service.login.LoginServiceImpl"
            scope="singleton">
            <property name="userDao" ref="userDao"></property>
            <property name="loginDao" ref="loginDao"></property>
        </bean>

    6.com.chinasoft.service.login.LoginServiceImpl
    此处注意的是servie层开始面向接口编程,一个接口,一个实现类.我们调用的都是实现类

    public SysUser findUserByLoginName(String pLoginName) {
            try {
                System.out.println("1111111");
                return userDao.findUserByLoginName(pLoginName);
            } catch (DataAccessException e) {
                e.printStackTrace();
                throw new BusinessException("出现系统错误,请与管理员联系",e);
            }
        }

    7.ApplicationContext-dao.xml

    <bean id="userDao" class="com.chinasoft.dao.user.UserDaoImpl"
            scope="singleton">
            <property name="hibernateTemplate" ref="hibernateTemplate"></property>
        </bean>

    8.com.chinasoft.dao.user.UserDaoImpl.java

    public SysUser findUserByLoginName(String ploginName) {
            String hql = "from SysUser where loginName = ?";
            List<SysUser> users = getHibernateTemplate().find(hql, ploginName);
            if (users.isEmpty()) {
                return null;
            } else {
                System.out.println("user根据用户名查询普通用户信息成功!");
                return users.get(0);
            }
        }

    这里就到了查表了,但是我们实体类是怎么和表对应的啊?  我们用的是hibernate,这个ORM很强大,真的很强大. 我这么配置的
    9.SysUser.hbm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
              <!-- class的name是实体类 table是表名  dynamic-insert,dynamic-update是说和表进行比较 只改变被改变的值,未变动的值不做处理-->
     <class name="com.chinasoft.model.user.SysUser" table="SYS_USER" dynamic-insert="true" dynamic-update="true">
       <!-- id是主键  name是对应的实体类的属性  column对应表中的字段   generator是设置主键增长方式-->
      <id name="userId" column="USER_ID">
       <generator class="sequence">
        <param name="sequence">SEQ_SYS_USER</param>
       </generator>
      </id>
       <!-- property是其他属性与表对应的固定方式   name属性 column表的字段 type  表中字段类型-->
      <property name="birthday" column="BIRTHDAY" type="date"></property>
      <property name="email" column="EMAIL" type="string"></property>
      <property name="imageUrl" column="IMAGE_URL" type="string"></property>
      <property name="loginName" column="LOGIN_NAME" type="string"></property>
      <property name="isMale" column="IS_MALE" type="true_false"></property>
      <property name="password" column="PASSWORD" type="string"></property>
      <property name="registerTime" column="REGISTER_TIME" type="timestamp"></property>
      <property name="userName" column="USER_NAME" type="string"></property>
      <property name="isLock" column="IS_LOCK" type="yes_no"></property>
      <property name="phoneNum" column="PHONE_NUM" type="string"></property>
       <!-- 多对一  永远是在多的一方进行配置-->
      <!-- 与职位关联配置 -->
      <many-to-one name="sysJob" class="com.chinasoft.model.job.SysJob" column="JOB_ID">
      </many-to-one>
      <!-- 与登录关联配置 -->
      <set name="sysLogin" table="SYS_LOGIN" inverse="true" fetch="select">
       <key>
        <column name="USER_ID"></column>
       </key>
       <one-to-many class="com.chinasoft.model.login.SysLogin"/>
      </set>
      
       <!-- 与作品表关联-->
            <set name="products" table="PRODUCT" inverse="true" fetch="select">
                <key>
                    <column name="CREATE_USER" >
                    </column>
                </key>
                <one-to-many class="com.chinasoft.model.product.Product" />
            </set>
            <!-- 与作品查询表关联-->
            <set name="productQuerys" table="PRODUCT_QUERY" inverse="true" fetch="select">
                <key>
                    <column name="USER_ID" >
                    </column>
                </key>
                <one-to-many class="com.chinasoft.model.product.ProductQuery" />
            </set>
           
             <!-- 与作品评论表关联-->
            <set name="porductComments" table="PRODUCT_COMMENT" inverse="true" fetch="select">
                <key>
                    <column name="USER_ID" >
                    </column>
                </key>
                <one-to-many class="com.chinasoft.model.comment.ProductComment" />
            </set>
           
            <!-- 与作品评论回复表关联-->
            <set name="commentReplys" table="COMMENT_REPLY" inverse="true" fetch="select">
                <key>
                    <column name="USER_ID" >
                    </column>
                </key>
                <one-to-many class="com.chinasoft.model.reply.CommentReply" />
            </set>
      
     </class>
    </hibernate-mapping>

    然后根据查询结果,action层会返回一个字符串,再去struts-login.xml中寻找对应的结果视图就完成了.
    前前后后两周多终于把SSH基本掌握了,恭喜自己!

  • 相关阅读:
    “随手记”APP与已经发布的记账软件“鲨鱼记账”的差距
    团队绩效打分
    “随手记”改进方案
    “随手记”第一阶段成果展示
    “随手记”意见整理
    针对每个团队的项目意见或建议
    “随手记”开发记录day10
    团队十日冲刺8
    团队十日冲刺7
    团队十日冲刺6
  • 原文地址:https://www.cnblogs.com/daweige/p/8183856.html
Copyright © 2011-2022 走看看