Spring MVC02

1.请求传参方式

2.日期类型处理

3.处理中文乱码问题

4.文件上传

5.文件下载

6.拦截器的使用

 

一、请求传参方式

1.情况一

最传统的方式,方法参数中带入request,通过request.getParameter("参数名"),再封装到JavaBean中(不要求掌握).

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2019/12/31 0031
  Time: 11:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <fieldset>
        <legend>请求方式一</legend>
        <form action="/request/test1" method="post">
            用户名:<input type="text" name="username"/>
            密码:<input type="text" name="password"/>
            <input type="submit" value="提交">
        </form>
    </fieldset>

</body>
</html>
package com.xj._04_request;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by Administrator on 2019/12/31 0031.
 */
@Controller
@RequestMapping("/request")
public class RequestController {
    @RequestMapping("/test1")
    public ModelAndView test1(HttpServletRequest request){

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        System.out.println(username);
        System.out.println(password);

        return null;
    }
}

   注:_03_response包下面的类中也有相同的方法test1,所以这里窄化了请求

2.情况二

简单类型参数和RequestParam注解(使用比较多).

        一:如果请求参数和Controller方法的形参同名.  可以直接接收.  

        二:如果请求参数和Controller方法的形参不同名. 使用@RequestParam注解贴在形参前,设置对应的请求参数名称.

(1)同名

    <fieldset>
        <legend>请求方式二</legend>
        <form action="/request/test2" method="post">
            用户名:<input type="text" name="username"/>
            密码:<input type="text" name="password"/>
            <input type="submit" value="提交">
        </form>
    </fieldset>
    @RequestMapping("/test2")
    public ModelAndView test2(String username,String password){
        System.out.println(username);
        System.out.println(password);
        return null;
    }

:简单数据类型的参数,可以直接使用方法的形参来接收,基于同名匹配原则。如果请求参数和Controller方法的形参不同名,接收不到数据,显示的都是null

(2)不同名

 

    @RequestMapping("/test2")
    public ModelAndView test2(@RequestParam("username") String Myname,
                              @RequestParam("password") String Mypwd){
        System.out.println(Myname);
        System.out.println(Mypwd);
        return null;
    }

      @RequestParam注解可以指定形参获取请求参数中哪个请求参数的值。凡是标注了 @RequestParam注解的属性,请求时就必须要传递请求参数。否则会报错

解决方法:加上默认的值

defaultValue:当没有该请求参数时,SpringMVC给请求参数的默认值

3.情况三

对象传参,能够自动把请求参数封装到声明在形参上的对象中,此时请求参数必须和对象的属性同名(使用比较多).

新建一个Employee类

@Setter@Getter
@ToString
public class Employee {
    private String username;
    private String password;
}
    <fieldset>
        <legend>请求方式三</legend>
        <form action="/request/test3" method="post">
            用户名:<input type="text" name="username"/>
            密码:<input type="text" name="password"/>
            <input type="submit" value="提交">
        </form>
    </fieldset>
    @RequestMapping("/test3")
    public ModelAndView test3(Employee employee){
        System.out.println(employee);
        return null;
    }

可以使用对象作为方法的形参,同时接收前台的多个请求参数,SpringMVC会基于同名匹配,将请求参数的值注入对应的对象中的属性中

注意:此时,SpringMVC会将对象参数直接放入request的作用域中,名称为类型首字母小写

新建一个前台界面

${employee}
    @RequestMapping("/test3")
    public ModelAndView test3(Employee employee){
        System.out.println(employee);

        ModelAndView mv = new ModelAndView();
        mv.setViewName("request/request");

        return mv;
    }

如果想改变key值,可以使用@ModelAttribute

@ModelAttribute作用如下

      1、设置请求参数绑定到Model对象中并传到视图页面的key名.

      2、将方法返回值或请求参数绑定到Model对象中并传到视图页面,设置key名.

4.情况四

数组和List集合类型参数.

(1)接收数组类型参数

    <fieldset>
        <legend>请求方式四</legend>
        <form action="/request/test4" method="post">
            <input type="checkbox" name="id" value="1">
            <input type="checkbox" name="id" value="2">
            <input type="checkbox" name="id" value="3">
            <input type="checkbox" name="id" value="4">
            <input type="submit" value="提交">
        </form>
    </fieldset>
    @RequestMapping("/test4")
    public ModelAndView test4(String id[]){//对于参数名相同的多个请求参数,可以直接使用数组作为方法的形参接收
        for(String i:id){
            System.out.println(i);
        }
        return null;
    }

(2)接收List类型参数

不能直接获取,只能通过对象封装List集合.

在Employee类中添加一条属性

private List<String> id;
    @RequestMapping("/test4")//使用对象中的集合属性接收
    public ModelAndView test4(Employee employee){

        for(String i:employee.getId()){
            System.out.println(i);
        }

        return null;
    }

5.情况五

RESTful是一种软件架构风格,严格上说是一种编码风格,其充分利用 HTTP 协议本身语义从而提供了一组设计原则和约束条件。

主要用于客户端和服务器交互类的软件,该风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

在后台,RequestMapping标签后,可以用{参数名}方式传参,同时需要在形参前加注解@PathVarible,

    @RequestMapping("/employee/{id}")
    public ModelAndView delete(@PathVariable("id") Integer employeeId){
        System.out.println(employeeId);
        return null;
    }

:因为前面窄化请求路径,所以这里加上request

如果后面过个参数,可以继续添加

    @RequestMapping("/employee/{id}/{deptId}")
    public ModelAndView delete(@PathVariable("id") Integer employeeId,@PathVariable("deptId") Integer deptId){
        System.out.println(employeeId);
        System.out.println(deptId);
        return null;
    }

二、日期类型处理

浏览器传递String的时间格式到Controller中转换为Date类型:

(1)在Controller形参上添加上@DateTimeFormat(pattern="yyyy-MM-dd")

    <fieldset>
        <legend>传递日期类型</legend>
        <form action="/request/test5" method="post">
            <input type="input" name="birthday" />
            <input type="submit" value="提交">
        </form>
    </fieldset>
    @RequestMapping("/test5")
    public ModelAndView test5(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){
        System.out.println(birthday);
        return null;
    }

(2)在对象字段上添加上@DateTimeFormat(pattern="yyyy-MM-dd")

在实体类中添加一条属性

    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date birthday;
    @RequestMapping("/test5")
    public ModelAndView test5(Employee employee){
        System.out.println(employee.getBirthday());
        return null;
    }

三、处理中文乱码问题

在web.xml中配置请求编码过滤器

    <!--配置请求编码过滤器-->
    <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>
        <!--设置request作用域强制使用上述设置的编码-->
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--设置response作用域强制使用上述设置的编码-->
        <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>

四、文件上传

1、导包

<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.4</version>
</dependency>

2、上传页面

    <form action="/save" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username"/><br/>
        头像:<input type="file" name="file"/><br/>
        <input type="submit" value="保存"/>
    </form>

3、在mvc.xml中配置文件上传的解析器

    <!--文件上传的解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="1048576"/><!--设置文件上传的最大尺寸为1MB 1024*1024-->
    </bean>

4、配置控制器

@Controller
public class UploadController {
    @Autowired
    private ServletContext servletContext;

    @RequestMapping("/save")
    public ModelAndView save(MultipartFile file,String username) throws  Exception{
        //把文件对象,以流的方式写出到img的文件夹中
        String realPath = servletContext.getRealPath("/img");
        //创建保存到服务器的文件的路径
        String path = realPath+"/"+new Date().getTime()+file.getOriginalFilename();

        File f = new File(path);
        file.transferTo(f);
        return null;
    }
}

解决方法:在img文件夹下随便新建一个文件,然后重新编译

五、文件下载

1、在pom.xml中添加插件

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

2、下载页面(直接在上面传页面添加了)

<a href="/download?name=1577794385267jiushiliu.jpg">下载</a>

3、配置控制器

@Controller
public class DownloadController {
    @Autowired
    private ServletContext context;

    @RequestMapping("/download")
    public ModelAndView download(String name, HttpServletResponse response) throws Exception{

        response.setContentType("application/x-msdownload");

        response.setHeader("Content-Disposition","attachment;filename="+name);

        //把文件对象,以流的方式写出到img的文件夹中
        String realpath = context.getRealPath("/img");
        Files.copy(Paths.get(realpath,name),response.getOutputStream());

        return null;
    }
}

六、拦截器的使用

Spring MVC 的拦截器类似于Servlet 开发中的过滤器Filter,用于对Controller进行预处理和后处理。

使用SpringMVC拦截器步骤:

    1.定义拦截器类

          1.1 实现接口 org.springframework.web.servlet.HandlerInterceptor

          1.2 继承适配器:org.springframework.web.servlet.handler.HandlerInterceptorAdapter

    2.在applicationContext.xml中配置拦截器

拦截器方法的执行时机:

      1):preHandle:控制器方法执行之前执行,返回结果为true表示放行,如果返回为false,表示拦截(可以做权限拦截,登录检查拦截).

      2):postHandle:控制器方法执行后,视图渲染之前执行(可以加入统一的响应信息).

      3):afterCompletion:视图渲染之后执行(处理Controller异常信息,记录操作日志,清理资源等)

(1)定义拦截器第一种方式

1、拦截器

public class MyIntercepter implements HandlerInterceptor {
    @Override
    //前置拦截
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor.preHandle...");
        return false;
    }

    @Override
    //后置拦截
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor.postHandle..");
    }

    @Override
    //最终拦截(视图渲染之后)
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor.afterCompletion..");
    }
}

2、控制器

@Controller
public class MyController {

    @RequestMapping("/get")
    public ModelAndView get() {

        System.out.println("MyController.get...");

        return null;
    }
}

3、配置拦截器

    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--拦截什么样的路径-->
            <mvc:mapping path="/*"/>
            <!--拦截的全限定名-->
            <bean class="com.xj._06_intercepter.MyIntercepter"/>
        </mvc:interceptor>
    </mvc:interceptors>

没有打印控制器中的输出语句,如果将拦截器中的return语句,改为true,表示放行,则打印输出控制器中的输出语句

(2)定义拦截器的第二种方式

public class MyIntercepter2 extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor2.preHandle");
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor2.postHandle");
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor2.afterCompletion");
        super.afterCompletion(request, response, handler, ex);
    }
}
        <mvc:interceptor>
            <!--拦截什么样的路径-->
            <mvc:mapping path="/*"/>
            <!--拦截的全限定名-->
            <bean class="com.xj._06_intercepter.MyIntercepter2"/>
        </mvc:interceptor>

如果在控制器中添加窄化请求,改变url的访问路径

两个拦截器都没有拦截

原因:

/*  :  表示拦截所有的一级路径

/**  : 表示拦截任意多级路径

将拦截器1的拦截路径改为/**

在控制器中添加一个方法,假如不想拦截这个路径

    @RequestMapping("/list")
    public ModelAndView list(){

        System.out.println("MyController.list...");

        return null;
    }

get被拦截

list没有被拦截

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值