SpringMVC(二)文件上传,请求转发,重定向,json传递,异常处理,拦截器

目录

1.SpringMVC实现文件上传

2.请求转发

2.1原生方式

2.2forward关键字方式

2.3简单方式

3.重定向

3.1原生方式

3.2Redirect关键字

4.@SessionAttributes

4.1向session中添加

4.2向session中清除

5.静态资源访问

问题:

5.1方式一

5.2方式二

5.3方式三

6.关于json的传递

7.异常处理

7.1自定义异常处理器

7.2@ControllerAdvice

7.3web.xml

8.拦截器

8.1执行流程:

 8.2开发步骤:

8.3拦截器链


1.SpringMVC实现文件上传

添加依赖

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

页面

三要素:

  1. 必须以表单方式提交。
  2. 表单属性enctype必须为multipart/form-data
  3. 请求方式必须为post
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <form action="/user/fileUpload" method="post" enctype="multipart/form-data">
      用户名:<input type="text" name="userName"><br/>
      年龄:<input type="text" name="age"><br/>
      生日:<input type="text" name="birthday"><br/>
      性别:<input type="radio" name="gender" value="1">男
            <input type="radio" name="gender" value="0">女<br/>
      头像:<input type="file" name="photoFile"><br/>
      <button type="submit">提交</button>
    </form>
    <br/>
  </body>
</html>

spring-mvc.xml

配置多媒体解析器:CommonsMultipartResolver,其id必须是multipartResolver

<?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">


    <context:component-scan base-package="com.study"/>

    <!--对mvc组件进行增强-->
    <!--<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>-->
    <mvc:annotation-driven/>

    <!--配置自定义类型转换器-->
    <!--<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.study.converter.StringToDateConverter"/>
            </set>
        </property>
    </bean>-->

    <!--配置视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/><!--前缀-->
        <property name="suffix" value=".jsp"/><!--后缀-->
    </bean>

    <!--配置多媒体解析器,id不可以随意填写-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="5000000"/><!--设置文件最大字节-->
    </bean>
</beans>

controller

形参接收必须为MultipartFile类型。

@Controller
@RequestMapping("/user")
public class UserController {

    //形参接收类型必须为MultipartFile
    @RequestMapping("/fileUpload")
    public String fileUpload(User user, MultipartFile photoFile) throws IOException {

        //获取文件原始名称
        String originalFilename = photoFile.getOriginalFilename();
        //文件保存路径
        String filePath = "F://" + System.currentTimeMillis() + originalFilename;
        //将文件存储到指定位置
        photoFile.transferTo(new File(filePath));
        user.setPhoto(filePath);
        System.out.println(user);
        return "success";//默认使用请求转发的方式跳转
    }

}

2.请求转发

特点:

  1. 服务器内部转发。
  2. 浏览器地址栏不发生改变。
  3. 可以携带数据

2.1原生方式

        使用HttpServletRequest、HttpServletResponse

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/user/login" method="post">
    用户名:<input type="text" name="userName"><br/>
    密码:<input type="password" name="password"><br/>
    <button type="submit">原生方式请求转发</button>
</form>
<br/>
</body>
</html>

controller

@Controller
@RequestMapping("/user")
public class UserController {

    //原生方式实现请求转发
    @RequestMapping(value = "/login",name = "原生方式实现请求转发")
    public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        User user = new User();
        user.setUserName(userName);
        user.setPassword(password);
        request.setAttribute("user",user);
        //原生方式不走前端控制器,所以要写全路径名。
        request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
    }

    //形参接收类型必须为MultipartFile
    @RequestMapping("/fileUpload")
    public String fileUpload(User user, MultipartFile photoFile) throws IOException {

        //获取文件原始名称
        String originalFilename = photoFile.getOriginalFilename();
        //文件保存路径
        String filePath = "F://" + System.currentTimeMillis() + originalFilename;
        //将文件存储到指定位置
        photoFile.transferTo(new File(filePath));
        user.setPhoto(filePath);
        System.out.println(user);
        return "success";//默认使用请求转发的方式跳转
    }

}

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    用户名:${user.userName}<br/>
    姓名:${user.name}<br/>
    密码:${user.password}<br/>
</body>
</html>

2.2forward关键字方式

        使用Model模型存储数据。

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/user/login" method="post">
    用户名:<input type="text" name="userName"><br/>
    密码:<input type="password" name="password"><br/>
    <button type="submit">原生方式请求转发</button>
</form>
<br/>

<form action="/user/login1" method="post">
    用户名:<input type="text" name="userName"><br/>
    密码:<input type="password" name="password"><br/>
    <button type="submit">forward关键字请求转发</button>
</form>
<br/>
</body>
</html>

controller

@Controller
@RequestMapping("/user")
public class UserController {
    
    //forward关键字实现请求转发,直接接收参数
    @RequestMapping(value = "/login1",name = "原生方式实现请求转发")
    public String login1(String userName, String password, Model model){

        User user = new User();
        user.setUserName(userName);
        user.setPassword(password);
        //将数据放到model模型中,其实就是放入了request域
        model.addAttribute("user",user);
        //不走前端控制器,所以要写全路径名。
       return "forward:/WEB-INF/pages/success.jsp";
    }

    //原生方式实现请求转发
    @RequestMapping(value = "/login",name = "原生方式实现请求转发")
    public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        User user = new User();
        user.setUserName(userName);
        user.setPassword(password);
        request.setAttribute("user",user);
        //原生方式不走前端控制器,所以要写全路径名。
        request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
    }

    //形参接收类型必须为MultipartFile
    @RequestMapping("/fileUpload")
    public String fileUpload(User user, MultipartFile photoFile) throws IOException {

        //获取文件原始名称
        String originalFilename = photoFile.getOriginalFilename();
        //文件保存路径
        String filePath = "F://" + System.currentTimeMillis() + originalFilename;
        //将文件存储到指定位置
        photoFile.transferTo(new File(filePath));
        user.setPhoto(filePath);
        System.out.println(user);
        return "success";//默认使用请求转发的方式跳转
    }

}

2.3简单方式

        走视图解析器,有三种方式可以携带数据:

  1. 使用Model模型
        //简单方式
        @RequestMapping(value = "/login2",name = "简单方式实现请求转发")
        public String login2(String userName, String password, Model model){
            User user = new User();
            user.setUserName(userName);
            user.setPassword(password);
            //将数据放到model模型中,其实就是放入了request域
            model.addAttribute("user",user);
    
            return "success";
        }
  2. 使用HttpServletRequest
        @RequestMapping(value = "/login2",name = "简单方式实现请求转发")
        public String login2(String userName, String password, HttpServletRequest request){
            User user = new User();
            user.setUserName(userName);
            user.setPassword(password);
            request.setAttribute("user",user);
    
            return "success";
        }

  3. 使用ModelAndView
        @RequestMapping(value = "/login2",name = "简单方式实现请求转发")
        public ModelAndView login2(String userName, String password, HttpServletRequest request){
            ModelAndView modelAndView = new ModelAndView();
            User user = new User();
            user.setUserName(userName);
            user.setPassword(password);
            modelAndView.addObject("user",user);//存放数据
            modelAndView.setViewName("success");//设置转发页面
            return modelAndView;
        }

3.重定向

特点:

  1. 可以进行服务器外部转发.
  2. 浏览器地址栏发生改变.
  3. 无法携带数据

3.1原生方式

register.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<from>
    用户名:<input type="text" name="userName"/>
    密码:<input type="password" name="password"/>
    <button type="submit">注册</button>
</from>
</body>
</html>

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/user/login" method="post">
    用户名:<input type="text" name="userName"><br/>
    密码:<input type="password" name="password"><br/>
    <button type="submit">原生方式请求转发</button>
</form>
<br/>

<form action="/user/login1" method="post">
    用户名:<input type="text" name="userName"><br/>
    密码:<input type="password" name="password"><br/>
    <button type="submit">forward关键字请求转发</button>
</form>
<br/>

<form action="/user/login2" method="post">
    用户名:<input type="text" name="userName"><br/>
    密码:<input type="password" name="password"><br/>
    <button type="submit">简单方式请求转发</button>
</form>
<br/>

<a href="/user/toRegister">注册</a>
<br/>
</body>
</html>

controller

    @RequestMapping(value = "/toRegister",name = "原生方式实现重定向")
    public void toRegister(HttpServletResponse response) throws IOException {
        response.sendRedirect("/register.jsp");//不走视图解析器
    }

3.2Redirect关键字

controller

    @RequestMapping(value = "/toRegister",name = "redirect关键字实现重定向")
    public String toRegister(HttpServletResponse response) throws IOException {
        return "redirect:/register.jsp";
    }

4.@SessionAttributes

4.1向session中添加

        在类上添加@SessionAttributes(values)注解,表示在这个类中,任何像request域中添加指定的value,就会向session中存一份。

        属性也可以使用type,表示像request中添加指定类型的value,就会向session中存放。

4.2向session中清除

        清除使用@SessionAttributes存入session的数据。

@RequestMapping("/cleanSession")
public String cleanSession(SessionStatus sessionStatus) throws Exception{
    //        清除通过@SessionAttributes存储的数据
    sessionStatus.setComplete();
    return "success";
}

5.静态资源访问

问题:

        我们将静态资源放在 webapp下的images下,在WEB-INF外的资源可以直接访问,但是直接访问这个静态资源时,404了。

        这是因为我们在配置前端控制器的时候,设置的路径为“/”,表示除了jsp的访问都可以进入前端控制器。所以将发布路径后的“/images/1.png”当做一个请求去找对应的处理器去了,找不到当然就报404了。

        如何解决这种问题呢。

5.1方式一

        在spring的配置文件中加入以下配置。

<mvc:resources mapping="/images/**" location="/images/"/>

        mapping对应浏览器地址栏中发布路径后的地址。

        location对应项目中的目录。

5.2方式二

        如果使用DispatcherServlet,那么tomcat的DefaultServlet就失效了。

        但如果想使用tomcat默认servlet来处理静态资源在spring的配置文件中加入以下配置即可。

<mvc:default-servlet-handler/>

5.3方式三

        在前端控制器的过滤配置中,改为以下配置。

<servlet>
        <servlet-name>springMvc</servlet-name>
        <!--前端控制器-->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--初始化参数 将spring-mvc.xml加载-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value><!--不写的话默认加载springMvc-servlet.xml-->
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <!--
            /* 代表所有请求都可以进入前端控制器
            /  代表所有请求都可以进入前端控制器 不包含jsp
            *.do 代表以.do的请求可以进入前端控制器
        -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

        但是这样的话,我们需要将请求全部改为以.do结尾,不然就无法进入前端控制器找方法。

6.关于json的传递

        无法使用对象接收json,也无法将json对象返回到浏览器(因为视图解析器的原因)。

        @RequestBody 用于接收前端传递的请求体中的json数据, 并可以自动转换封装进指定的对象中。在接收参数的参数类型前加上此注解。

        @ResponseBody将响应的内容转成json并响应浏览器。在方法上添加此注解。

7.异常处理

7.1自定义异常处理器

  1. 自定义异常处理器实现HandlerExceptionResolver接口,实现方法。
  2. 并将自定义异常处理器类加入IOC容器即可。

7.2@ControllerAdvice

  1. 自定义一个类,无需实现方法。
  2. 自定义一个处理异常的方法,并在方法上添加@ExceptionHandler注解。
  3. 在类上添加@ControllerAdvice注解。
  4. 并且要让spring的包扫描扫到这个类即可。

7.3web.xml

        在web.xml中配置错误跳转页面。

8.拦截器

        Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理后处理。作用:在访问到一个方法时做判断,是否要进入这个方法。

8.1执行流程:

        只有在经过springMvc的前端控制器的请求才会触发拦截器。

        1.preHandle:在请求进入controller之前进行拦截。

        2.postHandle:controller(处理器)响应给前端控制器时拦截。

        3.afterCompletion:在页面进行渲染之后进行拦截。

 8.2开发步骤:

  1. 自定义一个拦截器,需要实现HandlerInterceptor接口。
  2. 重写其中的方法,包括preHandle,postHandle,afterCompletion。
  3. 如果在preHandle中返回false,则请求被拦截,无法想后续流程走。如果返回true,则会继续流程。
  4. 在spring的配置文件中,配置拦截器需要拦截的目标,格式如下:
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/user/**"/><!--需要拦截的请求-->
        <bean class="com.study.interceptor.LoginInterceptor"/><!--自定义的拦截器-->
    </mvc:interceptor>
</mvc:interceptors>

8.3拦截器链

        开发中拦截器可以单独使用,也可以同时使用多个拦截器形成一条拦截器链。

        开发步骤和单个拦截器是一样的,只不过注册的时候注册多个,注册的顺序就代表拦截器执行的顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值