栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springMVC学习笔记(3),处理器方法的参数,获取请求的参数值,包括解决中文乱码问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springMVC学习笔记(3),处理器方法的参数,获取请求的参数值,包括解决中文乱码问题

如果还没有阅读前面的笔记,可以点击下面的链接
springMVC学习笔记(1),开发第一个springMVC的web应用,包含实例的详细步骤和截图

springMVC学习笔记(2),包括三层架构与SSM的关系,springMVC中MVC模式的实现,配置视图解析器。

文章目录
  • 处理器方法的参数
    • 逐个参数接收
    • 请求参数中文乱码问题
    • 校正请求参数名@RequestParam
    • 对象参数接收

处理器方法的参数

我们要想获得用户输入的信息,或请求中所携带的其他参数,可以从处理器方法的参数中获得,这些参数会在用户发起请求时,前端控制器分配到指定处理器方法时(即框架系统自动调用该方法),由系统为这些参数赋值。程序员只需要在方法中直接使用这些参数即可。

处理器方法可以包含以下四类参数:

  • HttpServletRequst
  • HttpServletResponse
  • HttpSession
  • 请求中所携带的请求参数
    • 逐个接收
    • 对象接收

这些参数就是处理器方法的形式参数,在定义处理器方法时,需要使用哪种获得参数方式,就在形式参数中定义哪些参数,这些参数的值,会在调用时,由系统自动按一定的规则赋值。

public ModelAndView doSome(形式参数列表){ 
}

例如:

public ModelAndView doSome(HttpServletRequest httpServletRequest,
                               HttpServletResponse httpServletResponse,
                               HttpSession httpSession){
                 
}                   

下面代码,我们来在处理器方法中从HttpServletRequest参数中获得请求中的携带的参数name的值

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(HttpServletRequest request,
                               HttpServletResponse response,
                               HttpSession session){  
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","欢迎使用SpringMVC" + request.getParameter("name"));
        mv.addObject("fun","执行的是doSome方法");
        mv.setViewName("show");
        return mv;
    }

我们在地址栏中,直接输入请求,并通过?号来携带参数name=testname

逐个参数接收

我们也可以直接使用请求中参数的名称作为处理器方法的形参。要求:

  • 形参名与请求中参数的名称一致
  • 顺序没有要求
  • 类型可以是任意基本数据类型,请求参数默认都是使用String类型传递,如果形参使用其他参数类型,框架会在自动赋值时,进行类型转换,如果不能转换成功,则会出错,处理器方法将得不到执行。

例如使用以下代码来接收请求中的多个参数值

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(String name,int age){  
        ModelAndView mv = new ModelAndView();
        mv.addObject("name",name);
        mv.addObject("age",age);
        mv.setViewName("show");
        return mv;
    }

因为我们修改了Model中的数据,所以,在View(show.jsp)中,也相应的修改一下获取Model值的代码

    

show.jsp从request域中获取数据

姓名:${name}

年龄:${age}

测试结果:

当然,如果我们采用form进行POST提交,处理方法是一样的。这里就不做演示了。
但是,我们可能会遇到以下问题:

  • 参数值为空
  • 参数无法自动转换类型
  • 值为中文时为乱码
    首先,当参数值为空时,如果你的形参类型为String类型,空是允许的,只是值为空字符串而以。但是如果当形参为如int类型时,Tomcat会报错误

    400错误码,表示请求参数类型不匹配。原因是,在处理器方法的形式参数中,我们定义的是int age
    所以,系统在为形参自动赋值时,会将值自动按形参类型转型,但是,因为值为空,空值无法转型为int类型,所以,报错。这时候,在Tomcat的日志上,其实会显示异常信息

org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type ‘java.lang.String’ to required type ‘int’; nested exception is java.lang.NumberFormatException: For input string: “”

MethodArgumentTypeMismatchException是方法参数类型不匹配异常。
这时,我们可以将形式参数类型设置成为int的包装类型Integer,那么当参数值为空时,会被转型为null,不会报错。

    public ModelAndView doSome(String name,Integer age){
    }

测试结果:

但是,如果你的形参类型无论为int还是Integer,当参数得到的值为字母或其他字符,还是会出现方法参数类型不匹配异常。
有两种解决办法:

  • 在前端对数据类型和是否为空进行检测,这也是常用办法
  • 申明形式参数类型为String,然后在处理器方法中对数据进行检测和处理。但这其实还是和框架帮你进行类型转换是差不多的。所以,并不建议。
请求参数中文乱码问题

我们现在试试在请求中提交中文。

可以看出,当使用GET方法提交请求时,中文处理没有问题。但是如果我们改用POST方法进行提交呢?
下面在index.jsp中增加表单,使用POST方法来提交请求

姓名:
年龄:


点击“提交”按钮后,结果为:

可以看出,当使用POST方法提交请求时,中文数据出现了乱码。
如果学习过java web开发的同学,应该知道,我们可以在doPost方法中,使用request.setCharacterEncoding(“utf-8”)来指定POST的参数的字符集编码。

    public void doPost(HttpServletRequest request) throws UnsupportedEncodingException {
        request.setCharacterEncoding("utf-8");
    }

但是,这需要为每一个servlet的doPost方法都添加上这一条语句。

实际开发中,我们可以使用过滤器来解决乱码问题。
我们可以直接使用框架中提供的过滤器CharacterEncodingFilter
这个类在以下包中

由于我们已添加了依赖,所以,可以直接使用。

修改web.xml文件,添加注册过滤器申明

    
        characterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
    

其中,filter-name可以自定义,但一般设置为类名的首字母小写
CharacterEncodingFilter这个类有三个属性,需要在xml文件中来指定属性值。
我们可以通过Ctrl + 鼠标单击类名,来跟踪查看该类的定义,可以看到类的源码

public class CharacterEncodingFilter extends OncePerRequestFilter {
	@Nullable
	private String encoding;
	private boolean forceRequestEncoding = false;
	private boolean forceResponseEncoding = false;
	...
	}
  • encoding:编码名称
  • forceRequestEncoding:是否强制请求使用该编码,默认为false
  • forceResponseEncoding:是否强制响应使用该编码,默认为false

因此,继续修改web.xml文件,设置过滤器的属性值。

    
        characterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            utf-8
        
        
            forceRequestEncoding
            true
        
        
            forceResponseEncoding
            true
        
    

设置编码为utf-8,并强制要求request和response都使用该编码。

下面再添加过滤器映射,设置哪些请求将应用这个过滤器,我们是将所有请求都使用这个过滤器。

    
        characterEncodingFilter
        /*
    

现在,我们设置好了过滤器,/*表示对所有请求都强制过滤器,即使用utf-8编码。我们再看一下效果。

可以看到。现在不管是通过GET还是POST请求,中文处理都正常了。

校正请求参数名@RequestParam

前面我们要求,处理器方法的形参名称,要求和请求的参数名称相同。如果因为开发的某些原因,不相同,我们该怎么办。

可以使用@RequestParam注解形参,来指定请求中的参数名称。如下:

姓名:
年龄:

现在请求参数名称为myname和myage,但我们处理器参数希望继续保持name和age,我们可以为形参加上@RequestParam注解

    public ModelAndView doSome(@RequestParam("myname") String name,
                               @RequestParam("myage") Integer age){
    	...
    }

@RequestParam注解除了value属性外,还有一个required属性,表示,是否一定要有该参数。默认为true,这时,如果请求中缺少这个参数,会出现400错误。

当你认为有些参数在提交时,也可以没有时,可以将required属性设置为false

首先,当没有设置required属性时,这个属性值采用默认值true。

当我们直接在地址栏中输入http://localhost:8080/hello/user/some.do,发起请求时,不携带任何参数

可以看到,会出现400错误,为缺少请求参数。

下面,我们设置required属性值为false

    public ModelAndView doSome(@RequestParam(value = "myname",required = false) String name,
                               @RequestParam(value = "myage",required = false) Integer age){
     	...
	}                              

再尝试在地址栏中直接输入请求URL,不携带任何参数

没有报错,只是说没有得到相应的参数值。

对象参数接收

当提交的参数较多时,如果继续使用处理器方法形参来列出所有的参数,会不太方便。

我们可以直接把一个自定义类的对象作为处理器方法的形参。这个类的各属性与提交的参数名称相同,类型也可以相一致,并为这些属性添加getter和setter方法,框架在调用这个处理器方法时,会自动产生一个这个类的对象,并通过这个类的setter方法来将提交的参数的值分别为这个对象的各属性赋值,最后,将这个对象通过处理器方法的形参传给处理器方法。程序员可以直接在方法中使用这个对象,并通过这个对象的getter方法来获得各属性值中保存的提交参数值。

我们需要先定义一个类(VO,value object,值对象),比如你是要添加一个学生,提交的信息是学生信息,我们需要创建一个值对象类Student,其需要提交的参数与Student类的各属性名称和类型相同(主要是需要类的属性名称与请求的参数名称要相同)。

例如,我们需要提交的是学生的name和age

姓名:
年龄:

我们可以定义一个VO类Student类,代码如下:

package com.javaoldman.vo;

public class Student {
    private String name;
    private  int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

为了方便打印对象信息,我们还重写了toString方法。

下面,就可以直接使用Student对象作为处理器方法的形参,并直接在方法中使用该对象来获取到提交的各参数值。前面说过,框架会在调用这个处理器方法前,先自动创建一个Student对象,并将请求中携带的参数按名称通过类的setter方法给对象的属性赋值。再将这个对象传给这个处理器方法。

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(Student student){
        ModelAndView mv = new ModelAndView();
        mv.addObject("student",student);
        mv.setViewName("show");
        return mv;
    }

在View视图文件show.jsp中,修改相应代码如下:

    

姓名:${student.name}

年龄:${student.age}

因为在View视图中,我们可以直接得到Model中的Student对象,名称叫student。所以,可以通过这个对象来访问相应的属性值。

通过对象形参来接收请求参数是我们较常用的方式,特别是当提交的参数个数较多时。

下一节,我们再讨论处理器方法的返回值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/692230.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号