mimiSSM商城项目总结

mimiSSM项目总结

一、配置文件

POM.xml文件
<?xml version="1.0" encoding="UTF-8"?>

<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>com.erha.mimissm</groupId>
  <artifactId>mimissm</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <junit.version>4.12</junit.version>
    <spring.version>5.2.5.RELEASE</spring.version>
    <mybatis.version>3.5.1</mybatis.version>
    <mybatis.spring.version>1.3.1</mybatis.spring.version>
    <mybatis.paginator.version>1.2.15</mybatis.paginator.version>
    <mysql.version>8.0.22</mysql.version>
    <slf4j.version>1.6.4</slf4j.version>
    <druid.version>1.1.12</druid.version>
    <pagehelper.version>5.1.2</pagehelper.version>
    <jstl.version>1.2</jstl.version>
    <servlet-api.version>3.0.1</servlet-api.version>
    <jsp-api.version>2.0</jsp-api.version>
    <jackson.version>2.9.6</jackson.version>
  </properties>

  <dependencies>
    <!-- spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</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-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jms</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- Mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis.spring.version}</version>
    </dependency>
    <dependency>
      <groupId>com.github.miemiedev</groupId>
      <artifactId>mybatis-paginator</artifactId>
      <version>${mybatis.paginator.version}</version>
    </dependency>
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>${pagehelper.version}</version>
    </dependency>
    <!-- MySql -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <!-- 连接池 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>${druid.version}</version>
    </dependency>

    <!-- junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>


    <!-- JSP相关 -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>${jstl.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <scope>provided</scope>
      <version>${jsp-api.version}</version>
    </dependency>
    <!-- Jackson Json处理工具包 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>20140107</version>
    </dependency>

    <!--    文件异步上传使用的依赖-->
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
  </dependencies>

  <build>
    <!--识别所有的配置文件-->
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>
</project>
1,1、后台配置文件
1.1.1数据库配置

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j46Bejdb-1633345391513)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20211004153431493.png)]

作用:

​ 1、获取数据库连接

​ 2、获取dao对象

通过与mybatis.xml文件搭配,SqlSessionFactoryBean获取dao层的Mappers文件,并通过MapperScannerConfigurer创建代理类加载到容器中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--声明数据源DataSource,作用是连接数据库的-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="url" value="${jdbc_url}"/>
        <property name="username" value="${jdbc_user}"/>
        <property name="password" value="${jdbc_password}"/>

        <property name="maxActive" value="20"/>
        <property name="initialSize" value="1"/>
        <property name="maxWait" value="6000"/>
        <property name="minIdle" value="1"/>

        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <property name="minEvictableIdleTimeMillis" value="300000"/>

        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>

        <property name="poolPreparedStatements" value="true"/>
        <property name="maxOpenPreparedStatements" value="20"/>

        <property name="asyncInit" value="true"/>
    </bean>

    <!--声明的是Mybatis中提供的sqlSessionFactoryBean类,这个类内部创建SqlSessionFactory的-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis.xml"/>
    </bean>

    <!--创建dao对象,使用SqlSessiona的getMapper(StudnetDao.class)
        MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.erha.mimissm.dao"/>
    </bean>

</beans>
1.1.2Mybatis配置文件

作用:

​ 1、配置sql语句日志

​ 2、配置分页

​ 3、加载dao文件下的Mappers文件

<?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>
    <!--日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!--分页查询-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor" />
    </plugins>

<!--    <typeAliases>-->
<!--        &lt;!&ndash;domain包中的类名就是别名&ndash;&gt;-->
<!--        <package name="com.erha.springssm.domain"/>-->
<!--    </typeAliases>-->

    <mappers>
        <!--加载dao包中的所有mapper文件-->
        <package name="com.erha.springssm.dao"/>
    </mappers>

</configuration>
1.1.3service配置文件

作用:

​ 1、扫描获取所有Service文件

​ 2、对每个Service文件内的方法逻辑配置事务

通过注解扫描器将service层对象加载到容器中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--扫描器-->
    <context:component-scan base-package="com.erha.mimissm.service"/>

    <!--事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--事务添加切入点-->
    <tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--查询类方法-->
            <tx:method name="*select*" read-only="true"/>
            <tx:method name="*find*" read-only="true"/>
            <tx:method name="*get*" read-only="true"/>
            <tx:method name="*search*" read-only="true"/>

            <!--添加类方法-->
            <tx:method name="*insert*" propagation="REQUIRED"/>
            <tx:method name="*save*" propagation="REQUIRED"/>
            <tx:method name="*add*" propagation="REQUIRED"/>

            <!--删除类方法-->
            <tx:method name="*delete*" propagation="REQUIRED"/>
            <tx:method name="*remove*" propagation="REQUIRED"/>
            <tx:method name="*clear*" propagation="REQUIRED"/>

            <!--修改类方法-->
            <tx:method name="*update*" propagation="REQUIRED"/>
            <tx:method name="*modify*" propagation="REQUIRED"/>
            <tx:method name="*change*" propagation="REQUIRED"/>
            <tx:method name="*set*" propagation="REQUIRED"/>

            <!--其他类型方法-->
            <tx:method name="*" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--切入点 (切入点表达式)-->
        <aop:pointcut id="mypointcut" expression="execution(* com.erha.mimissm.service.*.*(..))"/>

        <!--切面-->
        <aop:advisor advice-ref="advice" pointcut-ref="mypointcut"/>
    </aop:config>

</beans>
1.1.4Controller配置文件

作用:

​ 1、获取控制层的业务逻辑

​ 2、配置视图解析器,简化视图操作

​ 3、配置文件上传核心组件

​ 4、配置类型转换实现类,解决ajax请求的json格式

通过注解将Controller层的对象加载到容器中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--springmvc的配置文件:声明controller,视图解析器等web开发中的对象-->
    <context:component-scan base-package="com.erha.mimissm.controller"/>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/admin/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--设置文件上传核心组件-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    </bean>

    <!--
        作用:
        1、创建HttpMessageConverter接口的7个实现类对象,处理java对象到json。
        2、解决静态资源中,动态资源访问失败的问题。
    -->
    <mvc:annotation-driven/>

</beans>
1.2、前端配置文件
1.2.1、web.xml

作用:

​ 1、创建Spring容器

​ 2、配置中央调度器,与后台配置文件controller层文件相结合

​ 3、设置字符编码过滤器

<?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">
    <!--Spring框架容器-->
    <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>

    <!--中央调度器-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcherServlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

    <!--添加字符编码过滤器-->
    <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>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

二、业务逻辑

2.1MD5密码加密
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>

在密码框绑定失去焦点事件,在密码输入后,生成MD5格式密码,放于隐藏域中

<p>
    <span>密码:</span><input type="password" id="input_password" οnblur="md5()"/>
</p>
<script>
        function md5(){
            var input = document.getElementById("input_password");
            var md5_password = document.getElementById("md5_password");
            md5_password.value = md5(input.value);
        }
</script>

提交表单,用户名和MD5编译后的密码,登录成功将用户信息写入会话层

@RequestMapping(value = {"/login.action"},method = RequestMethod.POST)
public String login(String name, String pwd, HttpServletRequest request){
    Admin admin = adminService.login(name, pwd);
    if(admin != null){
        request.getSession().setAttribute("admin", admin); //将用户信息写入会话层中
        return "main";
    }else{
        request.setAttribute("errmsg", "用户名或密码不正确");
        return "login";
    }

2.2用户注册

绑定失去焦点事件,设定异步ajax请求,判断用户名是否存在

​ 注意:此时ajax请求返回格式是text文本格式,而不是json格式,同时Controller层在返回数据时也要对返回数据的格式进行设置

javaScript代码

<script type="text/javascript">
$(function () {
   $("#myname").blur(function () {
      if($("#myname").val() != ""){
         $.ajax({
            url:"${pageContext.request.contextPath}/admin/isExist.action",
            data:{"myname":$("#myname").val()},
            dataType:"text", 
            success:function (text) {
               if(text == "用户名已存在"){
                  $("#text").text(text);
                  $("#text").css("color","red");
               }else{
                  $("#text").text(text);
                  $("#text").css("color","green");
               }
            }
         })
      }
   });
});
</script>

页面代码

<tr>
   <td class="td1">用户名:</td>
   <td><input type="text" id="myname" placeholder="Username" class="td2" name="myname"></td>
</tr>

controller代码

@RequestMapping(value = {"/isExist.action"},produces = "text/plain;charset=utf-8")//设置返回数据格式
@ResponseBody
public String addAdmin(String myname){
    Admin admin = adminService.selectAdminByName(myname);
    if(admin != null){
        return "用户名已存在";
    }
    return "用户名可用";
}

service层代码

@Override
public Admin selectAdminByName(String myname) {
    AdminExample example = new AdminExample();
    AdminExample.Criteria criteria = example.createCriteria();
    criteria.andANameEqualTo(myname);
    List<Admin> admins = adminMapper.selectByExample(example);
    if(admins.size()>0){
        return admins.get(0);
    }else{
        return null;
    }
}
2.2分页
2.2.1无条件分页

使用请求完成数据获取,一般都是商品页面跳转时使用

跳转源头:

<a href="${pageContext.request.contextPath}/prod/split.action" target="myright" >
   <li class="two"><span class="glyphicon glyphicon-book" style="color: white;"></span>&nbsp;&nbsp;&nbsp;&nbsp;商品管理&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
</a>

在这里插入图片描述

控制层的获取数据:

@RequestMapping(value = {"/split.action"})
public String split(HttpServletRequest request,String page){
    PageInfo<ProductInfo> pageInfo = null;
    if(page == null){
        pageInfo = productInfoService.splitProductInfoPage(1, PAGE_SIZE);
    }else{
        pageInfo = productInfoService.splitProductInfoPage(Integer.parseInt(page), PAGE_SIZE);
    }
    request.setAttribute("info",pageInfo);
    //默认转发
    return "product";
}

判断查看页面数是否为空,若为空默认执行查找第一页,将数据装入pageinfo页面类的结果集中,并将其写入请求中,将请求转发到商品展示页面,包括内部的页码信息

页面数据展示:

<table class="table table-bordered table-striped">
    <tr>
        <th></th>
        <th>商品名</th>
        <th>商品介绍</th>
        <th>定价(元)</th>
        <th>商品图片</th>
        <th>商品数量</th>
        <th>操作</th>
    </tr>
    <c:forEach items="${info.list}" var="p">
        <tr>
            <td valign="center" align="center"><input type="checkbox" name="ck" id="ck" value="${p.pId}" οnclick="ckClick()"></td>
            <td>${p.pName}</td>
            <td>${p.pContent}</td>
            <td>${p.pPrice}</td>
            <td><img width="55px" height="45px"
                     src="/image_big/${p.pImage}"></td>
            <td>${p.pNumber}</td>
                <%--<td><a href="${pageContext.request.contextPath}/admin/product?flag=delete&pid=${p.pId}" οnclick="return confirm('确定删除吗?')">删除</a>--%>
                <%--&nbsp;&nbsp;&nbsp;<a href="${pageContext.request.contextPath}/admin/product?flag=one&pid=${p.pId}">修改</a></td>--%>
            <td>
                <button type="button" class="btn btn-info"
                        οnclick="one(${p.pId},${info.pageNum})">编辑
                </button>
                <button type="button" class="btn btn-warning" id="mydel"
                        οnclick="del(${p.pId},${info.pageNum})">删除
                </button>
            </td>
        </tr>
    </c:forEach>
</table>
2.2.2有条件分页

在这里插入图片描述

这一般是页面内部页面跳转,或商品查询时使用到的业务逻辑。

在普通页面的跳转时也会调用此方法,页面商品筛选同样也是这样的。一般使用ajax请求实现异步更新,在发起请求时,会将页面的条件全部获取到并通过ajax请求传送给Controller层

<!--分页的AJAX实现-->
<script type="text/javascript">
    function ajaxsplit(page) {
        var pname = $("#pname_cond").val();
        var typeid = $("#typeid_cond").val();
        var lprice = $("#lprice").val();
        var hprice = $("#hprice").val();
        //异步ajax分页请求
        $.ajax({
        url:"${pageContext.request.contextPath}/prod/pageCondition.action",
            data:{"page":page,"pname":pname,"typeid":typeid,"lprice":lprice,"hprice":hprice},
            type:"get",
            success:function () {
                //重新加载分页显示的组件table
                //location.href---->http://localhost:8080/admin/login.action
                $("#table").load("http://localhost:8080/mimissm/admin/product.jsp #table");//局部更新格式
            }
        })
    };</script>

Controller控制端代码:

@RequestMapping(value = {"pageCondition.action"})
@ResponseBody
public void PageCondition(HttpSession session, String page, String pname, String typeid, String lprice, String hprice){
    PageInfo<ProductInfo> pageInfo = null;
    if(page.length() == 0){
        pageInfo = productInfoService.splitProductInfoPageCondition(pname,typeid,lprice,hprice,"1", PAGE_SIZE);
    }else{
        pageInfo = productInfoService.splitProductInfoPageCondition(pname,typeid,lprice,hprice,page, PAGE_SIZE);
    }
    session.setAttribute("info",pageInfo);//将查询到的数据写入会话层,实现页面没有页面跳转完成页面刷新
}

service层代码:

@Override
public PageInfo<ProductInfo> splitProductInfoPageCondition(String Pname, String typeid, String lprice, String hprice, String pageNum, Integer pageSize) {
    PageHelper.startPage(Integer.parseInt(pageNum), pageSize);
    ProductInfoExample example = new ProductInfoExample();
    ProductInfoExample.Criteria criteria = example.createCriteria();
    if(!Pname.isEmpty()){
        criteria.andPNameEqualTo(Pname);
    }
    if(Integer.parseInt(typeid) > 0){
        criteria.andTypeIdEqualTo(Integer.parseInt(typeid));
    }
    if(lprice.length() != 0){
        criteria.andPPriceGreaterThanOrEqualTo(Integer.parseInt(lprice));
    }
    if(hprice.length() != 0){
        criteria.andPPriceLessThanOrEqualTo(Integer.parseInt(hprice));
    }
    example.setOrderByClause("p_id desc");
    List<ProductInfo> productInfos = productInfoMapper.selectByExample(example);
    PageInfo<ProductInfo> pageInfo = new PageInfo<>(productInfos);
    return pageInfo;
}

请求参数:

若使用Dom方法获取元素的value时,当value不存在时,请求参数默认请求的是:"" 长度为0的字符串

发送请求时若请求参数不存在(未定义),则为null,Controller获取到的请求参数为null

请求参数存在(定义了)但值为空,则默认为:”“ 长度为0的字符串

2.3图片上传

使用到的配置文件

<!--设置文件上传核心组件-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

在这里插入图片描述

添加信息页面中图片上传,其中文件发生改变时(选择文件后)就会触发事件,将选择的文件进行上传,后生成图片名称,将其保存到指定的路径下,将生成的文件名称返回给页面保存到隐藏域中,后续若再次更改时,将图片名称进行同请求一起提交,根据图片名称在将指定文件重写为新的文件。表单提交时提交到数据库的是文件的名称,展示时,将此文件名与指定的路径进行拼接,即可得到图片。

<td class="three">图片介绍</td>
  <td> <br>
      <div id="imgDiv" style="display:block; width: 40px; height: 100px;">
         <img id="getImg" width="100px" height="100px"/>
      </div>
   <br>
   		<input type="hidden" id="pimageName" name="pimageName">
    	<input type="file" id="pimage" name="pimage" οnchange="fileChange(this)"/>
     	<span id="imgName" ></span><br>
  </td>

文件上传触发事件:

当文件栏内容发生改变时就文件转存好,不与提交表单数据库添加数据混用

原因:起初文件名称隐藏域并没有文件名称。提交表单时,只要提交按钮点击,就已经把提交的数据封装好了,若此时进行单击事件对文件进行转存生成文件名,对提交的数据没有任何影响,提交的文件名称为空。

<script type="text/javascript">
function fileChange(file) {
   $("#getImg").attr("src",window.URL.createObjectURL(file.files[0]));//获取页面加载的图片地址来进行回显
   FileUpload();
}

上传请求FileUpload()

url请求地址中将隐藏域中的文件名称进行一同提交

<script type="text/javascript">
function FileUpload(){
   $.ajaxFileUpload({
      url: "${pageContext.request.contextPath}/prod/ajaxImg.action?pimageName="+$("#pimageName").val(),//用于文件上传的服务器端请求地址
      secureuri: false,//安全提交一般设置为false
      fileElementId: 'pimage',//文件上传控件的id属性
      dataType: 'json',
      success: function(obj)
      {
         console.log("ajax请求成功! obj = "+obj.imgurl);
         $("#pimageName").val(obj.imgurl);
      },
      error: function (e)//服务器响应失败处理函数
      {
         alert(e.message);
      }
   });
}

Controller层代码

先判断是否存在文件名称,若不存在pimageName.isEmpty() 则生成一个文件名称供其使用,并将文件上传到指定的路径下以此文件名进行转存。若存在文件,则直接将此文件名下的文件进行重写。确保一个添加页面只能使用一个文件名称对应一个文件空间

@RequestMapping("/ajaxImg.action")
@ResponseBody
public Object ajavImg(MultipartFile pimage,String pimageName){
    if(pimageName.isEmpty()) {
        pimageName = FileNameUtil.getUUIDFileName()+FileNameUtil.getFileType(pimage.getOriginalFilename());//获取文件名包括文件类型
    }else{
        System.out.println(pimageName);
        deleteImg(pimageName);
    }
    //提取文件名
    String saveFileName = pimageName;
    String staticPath = "D:\\mimissm\\src\\main\\webapp\\image_big";
    //转存
    try {
        pimage.transferTo(new File(staticPath+File.separator+saveFileName)); //不存在创建一个,存在就重写文件
        System.out.println("转存成功!");
    } catch (IOException e) {
        System.out.println("上传出错");
        e.printStackTrace();
    }

    JSONObject jsonObject = new JSONObject();
    jsonObject.put("imgurl", saveFileName);
    return jsonObject.toString();
}

取消添加:

取消添加时,判断此添加页面有没有生成一个文件名称(获取存放文件名称隐藏域的数据),若存在文件名称,则将此文件名称与指定的文件路径进行拼接,将得到的文件清除

<input type="reset" value="取消" class="btn btn-default" οnclick="myclose()">
<script type="text/javascript">
   function myclose() {
      window.location="${pageContext.request.contextPath}/prod/close.action?pimageName="+$("#pimageName").val();
   }
@RequestMapping(value = {"/close.action"})
public String close(String pimageName,String page){
    if(!pimageName.isEmpty()){ //判断文件名称是否存在
        deleteImg(pimageName);
    }
    if(page == null){ //判断请求参数有没有page
        return "redirect:/prod/split.action";
    }else{
        return "redirect:/prod/split.action?page="+page;
    }
}
public void deleteImg(String pimageName){
        String staticPath = "D:mimissm\\src\\main\\webapp\\image_big";
        if(!pimageName.isEmpty()){
            File file = new File(staticPath + File.separator + pimageName);
            if(file.exists()){
                file.delete();
            }
        }
    }

编辑时也同理,不同点在于其已经存在一个文件名称,页面初始化时就将文件名称放入隐藏域中。文件转存时不需要再重新创建一个文件名。添加判断,可于添加中文件转存一同使用。

不同点在于取消和文件转存

文件转存:此时文件转存要和修改的信息表单提交一同执行,当提交按钮单击触发单击事件检测提交信息,并完成文件转存(重写)。这里是因为页面起初已经有了文件名称,不必再重新生成,只需要文件转存执行就行。编辑时数据库中的文件名称不会发生改变,只改变此文件名规定路径下的文件(对文件进行重写)。

文件上传触发事件:

<tr>
   <td class="one">图片介绍</td>
   <td> <br><div id="imgDiv" style="display:block; width: 40px; height: 100px;">
      <img id="image_img" src="/image_big/${prod.pImage}" width="100px" height="100px" >
   </div><br><br>
      <input type="file" id="pimage" name="pimage" οnchange="fileChange(this)"/>
      <span id="imgName"></span><br>
   </td>
</tr>

<script type="text/javascript">
  function fileChange(file) {
	 $("#image_img").attr("src",window.URL.createObjectURL(file.files[0])); //图片上传框改变触发事件仅进行了页面回显
  }  
</script>

提交触发事件:

<input type="submit" value="提交" class="btn btn-success" οnclick="return ifnull()">
<script type="text/javascript">
    function FileUpload(){
        $.ajaxFileUpload({
            url: '${pageContext.request.contextPath}/prod/ajaxImg.action?pimageName='+$("#pimageName").val(),
            secureuri:false,
            fileElementId:'pimage',
            dataType:'json',
            success: function(obj)
            {
                $("#pimageName").val(obj.imgurl);
            },
            error: function (e)
            {
                alert(e.message);
            }
        });
    }
    function ifnull(){
        FileUpload();
        $("#pnameerr").text("");
        $("#pcontenterr").text("");
        $("#priceerr").text("");
        $("#numerr").text("");
        $("#typeIderr").text("");
        $("#pimageerr").text("");
        var err = 0;
        if($("#pName").val() == undefined || $("#pName").val()=="" || $("#pName").val()==null){
            $("#pnameerr").text("商品名称为空");
            err++;
        }if($("#pContent").val() == undefined || $("#pContent").val()=="" || $("#pContent").val()==null){
            $("#pcontenterr").text("商品介绍为空");
            err++;
        }if($("#pPrice").val()==undefined || $("#pPrice").val()=="" || $("#pPrice").val()==null){
            $("#priceerr").text("定价为空");
            err++;
        }if($("#pNumber").val()==undefined || $("#pNumber").val()=="" || $("#pNumber").val()==null){
            $("#numerr").text("总数量为空");
            err++;
        }if($("#typeId").val()==undefined || $("#typeId").val()=="" || $("#typeId").val()==null){
            $("#typeIderr").text("类别为空");
            err++;
        }
        if(err > 0){
            return false;
        }else{
            return true;
        }
    }
   </script>

取消:取消无需再对文件进行删除,若没进行提交,服务器中指定路径下的文件就不会被重写,原文件就不会发生改变。

<td>
   <input type="reset" value="取消" class="btn btn-default" οnclick="myclose()">
</td>
<script type="text/javascript">
	function myclose() {
		window.location="${pageContext.request.contextPath}/prod/closeUpdate.action?page="+$("#page").val();
	}
</script>

控制层代码

@RequestMapping(value = {"/closeUpdate.action"})
public String closeUpdate(String page){
    if(page.isEmpty()){
        return "redirect:/prod/split.action";
    }else{
        return "redirect:/prod/split.action?page="+page;
    }
}
$("#pNumber").val()==null){
            $("#numerr").text("总数量为空");
            err++;
        }if($("#typeId").val()==undefined || $("#typeId").val()=="" || $("#typeId").val()==null){
            $("#typeIderr").text("类别为空");
            err++;
        }
        if(err > 0){
            return false;
        }else{
            return true;
        }
    }
   </script>

取消:取消无需再对文件进行删除,若没进行提交,服务器中指定路径下的文件就不会被重写,原文件就不会发生改变。

<td>
   <input type="reset" value="取消" class="btn btn-default" οnclick="myclose()">
</td>
<script type="text/javascript">
	function myclose() {
		window.location="${pageContext.request.contextPath}/prod/closeUpdate.action?page="+$("#page").val();
	}
</script>

控制层代码

@RequestMapping(value = {"/closeUpdate.action"})
public String closeUpdate(String page){
    if(page.isEmpty()){
        return "redirect:/prod/split.action";
    }else{
        return "redirect:/prod/split.action?page="+page;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值