SpringMVC-three

一、上传文件

⊙客户端

1-客户端表单3要素

在这里插入图片描述

2、文件上传原理

在这里插入图片描述

⊙服务器端

1、单文件上传步骤

①pom.xml导包

导入fileupload和io坐标

<dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
    
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.3</version>
    </dependency>
②springmvc.xml配置文件上传解析器

在这里插入图片描述

测试: ③controller编写代码
@RequestMapping("/quick16")
    @ResponseBody
    public void save16(String username, MultipartFile uploadFile) {//uploadFile要跟表单的name一致;MultipartFile是用来上传的文件的
        System.out.println(username);
        System.out.println(uploadFile);
    }

输出:

lizhxi
org.springframework.web.multipart.commons.CommonsMultipartFile@49afbd7c

③保存文件:③controller编写代码

@RequestMapping("/quick16")
    @ResponseBody
    public void save16(String username, MultipartFile uploadFile) throws IOException {//uploadFile要跟表单的name一致;MultipartFile是用来上传的文件的
        //获取上传文件名称
        String originalFilename = uploadFile.getOriginalFilename();
        //存储文件
        uploadFile.transferTo(new File("C:\\aaa\\"+originalFilename));//transfer To:转移 到
    }

2、多文件上传

①多参式

客户端:

<form action="${pageContext.request.contextPath}/user/quick16" method="post" enctype="multipart/form-data">
    名称<input type="text" name="username"><br>

    文件1<input type="file" name="uploadFile"><br>	<!--uploadFile-->
    文件2<input type="file" name="uploadFile2"><br>	<!--uploadFile2-->

    <input type="submit" value="上传">
</form>

controller:

  @RequestMapping("/quick16")
    @ResponseBody                               //MultipartFile的引用变量一定要跟表单项一致,才能被注入
    public void save16(String username, MultipartFile uploadFile, MultipartFile uploadFile2) throws IOException {//uploadFile要跟表单的name一致;MultipartFile是用来上传的文件的
        //获取上传文件名称
        String originalFilename = uploadFile.getOriginalFilename();
        String originalFilename2 = uploadFile.getOriginalFilename();
        //存储文件
        uploadFile.transferTo(new File("C:\\aaa\\"+originalFilename));
        uploadFile.transferTo(new File("C:\\aaa\\"+originalFilename2));
    }

②数组式

客户端:

<form action="${pageContext.request.contextPath}/user/quick16" method="post" enctype="multipart/form-data">
    名称<input type="text" name="username"><br>

    文件1<input type="file" name="uploadFile"><br><!--uploadFile要一致-->
    文件2<input type="file" name="uploadFile"><br>
    文件2<input type="file" name="uploadFile"><br>
    文件2<input type="file" name="uploadFile"><br>
    文件2<input type="file" name="uploadFile"><br>

    <input type="submit" value="上传">
</form>

controller:

    @RequestMapping("/quick16")
    @ResponseBody                               //MultipartFile的引用变量一定要跟表单项一致,才能被注入
    public void save16(String username, MultipartFile[] uploadFile) throws IOException {//uploadFile要跟表单的name一致;MultipartFile是用来上传的文件的
        //遍历数组
        for (MultipartFile multipartFile : uploadFile) {
            //获取上传文件名称
            String originalFilename = multipartFile.getOriginalFilename();
            //存储文件
            multipartFile.transferTo(new File("C:\\aaa\\"+originalFilename));
        }
    }

在这里插入图片描述

二、SpringMVC拦截器

在这里插入图片描述
在这里插入图片描述

1、快速入门

①编写controller目标方法

    @RequestMapping("/quick2")
    public ModelAndView save2() {
        System.out.println("我是目标方法。。");
        //创建视图对象
        ModelAndView modelAndView = new ModelAndView();
        //存储数据到request
        modelAndView.addObject("username", "LiZhiXi");
        //绑定视图资源
        modelAndView.setViewName("success");        //指定显示的页面(前后缀被配置了)
        return modelAndView;    //返回视图对象(转发页面)
    }

②编写MyInterceptor1实现HandlerInterceptor接口

public class MyInterceptor1 implements HandlerInterceptor {
    //执行:目标方法执行之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("我是preHandle。。。。");
        return true;//false表示拦截访问资源
    }
    //执行:目标方法执行之后,视图对象返回之前
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("我是postHandle。。。。");
    }
    //执行:目标方法结束后
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("我是afterCompletion。。。。");
    }
}

③springmvc.xml配置拦截器

    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--设置对哪些资源进行拦截操作:所有-->
            <mvc:mapping path="/**"/>
            
            <!--告诉spring我这个是拦截器-->
            <bean class="com.itheima.controller.MyInterceptor1"/>
            
        </mvc:interceptor>
    </mvc:interceptors>

④index.jsp

<h2>Hello World!${name}</h2>

输出:

index.jsp

Hello World!LiZhiXi

控制台:

我是preHandle。。。。
我是目标方法。。
我是postHandle。。。。
我是afterCompletion。。。。

执行流程顺序:
在这里插入图片描述

2、拦截器方法演示

在这里插入图片描述

①preHandle

作用:【在执行目标方法之前执行】

一般是使用request获取参数来进行拦截操作

    //执行:目标方法执行之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //拦截访问者获取param请求参数
        String param = request.getParameter("param");
        //判断请求参数是否存在or不一致
        if ("yes".equals(param)){
           //一致
            return true;    //放行访问

        }else {
            //没有or不一致,转发error页面
            request.getRequestDispatcher("/jsp/error.jsp").forward(request,response);
            return false;
        }
    }

②postHandle

特点:【目标方法返回视图对象之前(目标方法已经对视图对象进行了操作,只是还差返回这一步)】

一般用来操作视图对象

    //执行:目标方法执行之后,视图对象返回之前
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //重新设置视图对象中的键值对
        modelAndView.addObject("name","刘德华");   //将"lizhixi"改为“刘德华”
    }

③拦截器链

使用多个拦截器,这里只使用2个来意思意思。

1、配置springmvc.xml

 <!--配置拦截器1-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--设置对哪些资源进行拦截操作:所有-->
            <mvc:mapping path="/**"/>
            <!--告诉spring我这个是拦截器-->
            <bean class="com.itheima.controller.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>
    
    <!--配置拦截器2-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--设置对哪些资源进行拦截操作:所有-->
            <mvc:mapping path="/**"/>
            <!--告诉spring我这个是拦截器-->
            <bean class="com.itheima.controller.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

2、2个拦截器(省略)

这里要说的是,拦截器的优先执行顺序跟springmvc.xml配置的Bean的顺序有关。

  • 如果是拦截器1Bean在前,拦截器2在后
    在这里插入图片描述
  • 如果是拦截器2Bean在前,拦截器1在后
    在这里插入图片描述
    发现,哪个最优先的拦截器先出发,回来的时候就迟。(filter一样)
    在这里插入图片描述

三、拦截器案例:用户登录

1、分析

需求:用户必须登录才能访问资源
判断是否登录的依据:根据session是否有存储指定User对象来判断是否登录(服务器共享session对象域数据)
实现:自定义拦截器,并在preHandle进行判断。(有,放行;没有,跳转登录页面)
在这里插入图片描述

2、代码实现

1、springmvc.xml配置拦截器

<!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--设置对哪些资源进行拦截操作:所有-->
            <mvc:mapping path="/**"/>
            <!--告诉spring我这个是拦截器-->
            <bean class="com.itheima.controller.PrivilegeInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

2、自定义拦截器:

public class PrivilegeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断用户是否登录,本质:判断session中是否存在user
        User user = (User) request.getSession().getAttribute("user");
        if (user==null){
            //没有登录
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return false;
        }

        //放行,访问目标资源
        return true;
    }
}

3、客户端

表单提交的访问UserController中login方法。

<form action="${pageContext.request.contextPath}/user/login" method="post">

4、修改【springmvc.xml配置拦截器】

    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--设置对哪些资源进行拦截操作:所有-->
            <mvc:mapping path="/**"/>

            <!--配置哪些资源被排除拦截-->
            <mvc:exclude-mapping path="/user/login"/>
            
            <!--告诉spring我这个是拦截器-->
            <bean class="com.itheima.controller.PrivilegeInterceptor"/>
            
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

5、UserController

 @RequestMapping("/login")
    public String login(String username, String password, HttpSession session) {//springMVC帮你注入Servlet原始API对象引用
        //根据账户密码查询User
        User user = userService.login(username, password);
        //判断User是否存在
        if (user != null) {
            //User存在,登陆成功
                //将User存储到session中,不然会被拦截器拦截
            session.setAttribute("user",user);
          // return "redirect:/index.jsp";
          return "redirect:/index.jsp";  //使用转发更好:因为存储数据
        }
        //User不存在
        return "redirect:/login.jsp";    //返回页面(View)

四、Spring异常处理机制

①异常处理思路

异常从Dao–>Service–>Controller,最后抛给前端控制器解决,因为前端控制器是最终调用者,而前端控制器去找SpringMVC内置的异常处理器。
在这里插入图片描述

②SpringMVC异常处理方式

1、简单异常处理器SimpleMappingExceptionResolver

在这里插入图片描述
解析:

“SimpleMappingExceptionResolver”接受到抛出的异常会先去
----------------------------------------↓下面这里寻找(自定义的异常响应)↓---------------------------------------------

		<map>		异常类型		                             错误视图
            <entry key="com.itheima.exception.MyException" value="error"/>
            <entry key="java.lang.ClassCastException" value="error"/>
        </map>
        
------------------------------------如果找不到,才去执行这里(默认异常响应)-------------------------------------
		
		<property name=“defaultErrorView” value=“error”/>   默认错误视图
		
-----------------------------------下面是具体的介绍------------------------------
<property name=“defaultErrorView” value=“error”/>中name=“defaultErrorView”的defaultErrorView可能是简单异常处理器的属性吧,
			“error”表示【视图(页面)】,即,当抛出了异常,而且是没有配置的异常,就去跳转到指定页面(index.jsp、login.jsp、、、)。
			
【问:为什么可以直接写页面的名称呢?】
答:原本不是的,只是我们在spring-mvc中配置了视图解析器,将网页的前缀后缀都配置了。
--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--

		<map>		异常类型		                             错误视图
            <entry key="com.itheima.exception.MyException" value="error"/>		
            <entry key="java.lang.ClassCastException" value="error"/>
        </map>
key:表示异常的类的全限定名,当然这个“com.itheima.exception.MyException”是我自定义的异常(MyExpetion空的自定义类,继承了Exception)
value:同上

【问:跳转页面有什么用?】
当用户访问页面时出现异常,那么,如果在网页上直接报错显示500等等,用户体验不好。
我们可以使用遇到什么错,跳转什么页面的方式去“忽悠”用户。比如:访问人数较多,请稍后再来!~~

2、自定义异常处理在这里插入图片描述

1、创建自定义异常处理器,实现HandlerExceptionResolver接口

instanceof :用来判断一个对象是否为一个类的实例

public class ExceptionDemo01 implements HandlerExceptionResolver {
    /**
     *  参数:Exception:将抛出的异常封装成异常对象
     *  返回值:ModelAndView(视图):跳转到指定的错误页面
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        //创建视图对象
        ModelAndView modelAndView = new ModelAndView();
        //判断异常类型
        if (ex instanceof MyException){
            //存储数据
            modelAndView.addObject("error","自定义异常");
            modelAndView.setViewName("error1");//跳转视图
        }else if (ex instanceof ClassCastException){
            modelAndView.addObject("error","格式转换异常");
            modelAndView.setViewName("error2");//跳转视图
        }
        return modelAndView;
    }
}

2、springmvc.xml配置异常处理器

	 <!--配置自定义异常处理器-->
    <bean class="com.itheima.myException.ExceptionDemo01"/>

3、测试异常(省略)

如果出错的异常类型匹配就跳转相应的页面。

总结

在这里插入图片描述

spring-mvc.xml总配置
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--Controller组件扫描:让Spring去指定类扫描注解-->
    <context:component-scan base-package="com.itheima.controller"/>
    <!--配置内部资源视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前后缀-->
        <property name="prefix" value="/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--配置处理映射器器
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
            </list>
        </property>
    </bean>-->

    <!--放行访问web应用资源限制-->
<!---->
<!--    <mvc:resources mapping="/js/**" location="/js/"/>&lt;!&ndash;mapping:表示浏览器访问的映射地址;location:表示映射资源的实际地址&ndash;&gt;-->
<!--    <mvc:resources mapping="/img/**" location="/img/"/>-->
<!---->
    <mvc:default-servlet-handler/>
<!--    表示SpringMVC帮你找资源,找不到就交给Tomcat服务器(Tomcat容器内找)-->
    <!--mvc的注解驱动-->
    <mvc:annotation-driven conversion-service="conversionService"/>
    <!--声明类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters"><!--设置属性-->
            <list>
                <bean class="com.itheima.converter.DateConverter"/>     <!--叫工厂Bean帮我造个自定义转换器-->
            </list>
        </property>
    </bean>




<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--上传文件的总大小-->
<property name="maxInMemorySize" value="1024000"/>
    <!--单个文件上传的大小-->
    <property name="maxUploadSizePerFile" value="102400"/>
    <!--上传文件的编码类型-->
    <property name="defaultEncoding" value="UTF-8"/>
</bean>


<!--    &lt;!&ndash;配置拦截器1&ndash;&gt;
    <mvc:interceptors>
        <mvc:interceptor>
            &lt;!&ndash;设置对哪些资源进行拦截操作:所有&ndash;&gt;
            <mvc:mapping path="/**"/>
            &lt;!&ndash;告诉spring我这个是拦截器&ndash;&gt;
            <bean class="com.itheima.controller.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>

    &lt;!&ndash;配置拦截器2&ndash;&gt;
    <mvc:interceptors>
        <mvc:interceptor>
            &lt;!&ndash;设置对哪些资源进行拦截操作:所有&ndash;&gt;
            <mvc:mapping path="/**"/>
            &lt;!&ndash;告诉spring我这个是拦截器&ndash;&gt;
            <bean class="com.itheima.controller.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>-->


   <!-- &lt;!&ndash;配置拦截器&ndash;&gt;
    <mvc:interceptors>
        <mvc:interceptor>
            &lt;!&ndash;设置对哪些资源进行拦截操作:所有&ndash;&gt;
            <mvc:mapping path="/**"/>

            &lt;!&ndash;配置哪些资源被排除拦截&ndash;&gt;
            <mvc:exclude-mapping path="/user/login"/>
            <mvc:exclude-mapping path="/user/quick"/>
            <mvc:exclude-mapping path="/js/**"/>
            <mvc:exclude-mapping path="/css/**"/>
            <mvc:exclude-mapping path="/img/**"/>
            <mvc:exclude-mapping path="/pages/**"/>
            <mvc:exclude-mapping path="/plugins/**"/>

            &lt;!&ndash;告诉spring我这个是拦截器&ndash;&gt;
            <bean class="com.itheima.controller.PrivilegeInterceptor"/>
            
        </mvc:interceptor>
    </mvc:interceptors>
-->

    <!--配置自定义异常处理器-->
    <bean class="com.itheima.myException.ExceptionDemo01"/>
</beans>
applicationComtext.xml总配置
<?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 http://www.springframework.org/schema/context/spring-context.xsd">

<!--    导入jdbc配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
<!--    配置数据库连接池对象-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.url}"/>
        <property name="jdbcUrl" value="${jdbc.driver}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--配置jdbc模板对象-->
    <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="vo" class="com.itheima.domain.VO"/>
    <!--配置userDao-->
    <bean id="userDao" class="com.itheima.dao.Impl.UserDaoIpml">
    </bean>

    <!--配置UserService-->
    <bean id="userService" class="com.itheima.service.Impl.UserServiceIpml">
        <property name="dao" ref="userDao"/>
    </bean>
    <context:component-scan base-package="com.itheima"/>
</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值