04-SpringMVC获取参数处理参数以及页面跳转问题

文章目录

    • 五、获取参数数据处理以及页面跳转
      • 请求转发和请求重定向
        • 5.1、ServletAPI方式跳转
        • 5.2、SpringMVC方式跳转
          • (1)通过SpringMVC来实现转发和重定向 - 无需视图解析器
          • (2)通过SpringMVC来实现转发和重定向 - 有视图解析器;
      • 数据处理
        • 5.1、获取前端提交的数据 和 处理提交数据
          • 1、提交的域名称和处理方法的参数名一致
          • 2、提交的域名称和处理方法的参数名不一致
          • 3、提交的是一个对象
        • 5.2、设置数据显示在前端
          • 第一种 : 通过ModelAndView(不常用)
          • 第二种 : 通过ModelMap(不常用)
          • 第三种 : 通过Model(常用)
          • 三种方式对比
        • 5.3、乱码问题

五、获取参数数据处理以及页面跳转

请求转发和请求重定向

5.1、ServletAPI方式跳转

通过设置ServletAPI , 不需要视图解析器 ,如下

1、通过HttpServletResponse进行输出

2、通过HttpServletResponse实现重定向

3、通过HttpServletResponse实现转发

@Controller
public class ResultGo {

   @RequestMapping("/result/t1")
   public void test1(HttpServletRequest req, HttpServletResponse rsp) throwsIOException {
       rsp.getWriter().println("Hello,Spring BY servlet API");
  }

   @RequestMapping("/result/t2")
   public void test2(HttpServletRequest req, HttpServletResponse rsp) throwsIOException {
       rsp.sendRedirect("/index.jsp");
  }

   @RequestMapping("/result/t3")
   public void test3(HttpServletRequest req, HttpServletResponse rsp) throwsException {
       //转发
       req.setAttribute("msg","/result/t3");
       req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
  }

}

5.2、SpringMVC方式跳转

(1)通过SpringMVC来实现转发和重定向 - 无需视图解析器

直接return为默认转发到指定的路劲页面下

@Controller
public class ResultSpringMVC {
    //转发1(默认的方式):直接return指定页面的路径
   @RequestMapping("/rsm/t1")
   public String test1(){
       //转发
       return "/index.jsp";
  }

    //转发2:使用前缀forward:告诉处理器为转发到指定的路径页面
   @RequestMapping("/rsm/t2")
   public String test2(){
       //转发二
       return "forward:/index.jsp";
  }
   //重定向:同理,使用前缀redirect:告诉处理器为重定向到指定的路径页面
   @RequestMapping("/rsm/t3")
   public String test3(){
       //重定向
       return "redirect:/index.jsp";
  }
}
(2)通过SpringMVC来实现转发和重定向 - 有视图解析器;

重定向,不需要视图解析器,因为重定向本质上就是一个新的请求,所有就不要视图解析器了**,需要我们使用前缀“redirect来指明为重定向”**,我们只需要注解路径问题

转发:return “视图名” ;默认就是转发到 {视图解析器前缀}+视图名+{视图解析器后缀}

@Controller
public class ResultSpringMVC2 {
   @RequestMapping("/rsm2/t1")
   public String test1(){
       //转发
       return "test";
  }

   @RequestMapping("/rsm2/t2")
   public String test2(){
       //重定向
       return "redirect:/index.jsp";
       //return "redirect:hello.do"; //hello.do为另一个请求/
  }
}

数据处理

5.1、获取前端提交的数据 和 处理提交数据

1、提交的域名称和处理方法的参数名一致

提交数据 : http://localhost:8080/hello?name=kunkun 处理方法 :springMVC自动获取参数名为name的参数值,并赋值给处理方法的同名参数

@RequestMapping("/hello")
public String hello(String name){//自动获取参数名为name的参数值,并赋值给处理方法的同名参数
   System.out.println(name);
   return "hello";
}
2、提交的域名称和处理方法的参数名不一致

提交数据 : http://localhost:8080/hello?username=kunkun

处理方法 :使用注解@RequestParam(“指定请求参数名”)修饰处理方法的参数,表示获取指定名字参数赋值给他所有修饰的方法

//@RequestParam("username") : username提交的域的名称 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){//表示获取参数名为username的参数值赋值给name,
   System.out.println(name);
   return "hello";
}

推荐使用第二种方式,无论是否请求参数名和处理方法参数名是否一样,我们都是用此注解修饰处理方法参数,因为可以简单明了知道是从前端获取参数,获取了那个参数值,防止乱套

3、提交的是一个对象

要求提交的表单域和对象的属性名一致 , 参数使用对象即可,但是有一个要求就是我们需要保持参数名和对象属性名称一样,SpringMVC自动为我们重前端请求地址获取参数值,按照参数的name属性为我们对象相同属性名注入(说白了就是使用set注入)

(1)实体类

public class User {
    private int id;
    private String name;
    private int age;
}

(2)提交数据:http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

(3)处理方法:

/**
 * 从前端接受的是一个对象:id,name,age
 * 1、接受前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
 * 2、假设传递的一个对象User,匹配User对象中的字段名:如果参数名和属性性名一致,则ok,否则匹配不到
 * 3、自动的为我们封装对象,按照属性名和参数名进行设置
 */
@GetMapping("/t2")
public String test2(User user) {
    System.out.println(user);
    return "test";
}

5.2、设置数据显示在前端

第一种 : 通过ModelAndView(不常用)
public class ControllerTest1 implements Controller {

   public ModelAndView handleRequest(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws Exception {
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","ControllerTest1");
       mv.setViewName("test");
       return mv;
  }
}
第二种 : 通过ModelMap(不常用)

ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("name",name);
   System.out.println(name);
   return "hello";
}
第三种 : 通过Model(常用)

Model

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("msg",name);
   System.out.println(name);
   return "test";
}
三种方式对比
  • Model只有几个方法适用与存储数据
  • ModelMap继承与LinkedMap,除了自身的一些方法外,同样的继承了LinkedMap的方法和特性
  • ModelAndView 即可以存储数据,又可以设置返回视图层,控制视图跳转逻辑
  • 一般情况下我们都是使用Model

5.3、乱码问题

当我们提交表单到服务器端,获取的参数值乱码,我们采用过滤器了解决乱码问题,SpringMVC给我们提供了一个过滤器,我们可以直接在web.xml中配置这个过滤器,一般情况下是不会发生乱码

<!--配置SpringMVC的乱码过滤器-->
<filter>
    <filter-name>encoding</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>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*

但是我们发现,在一些情况下,这个过滤器,对get请求支持不是很好:处理方法

1、修改Tomacat的配置文件:设置编码!

<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
          connectionTimeout="20000"
          redirectPort="8443" />

2、自定义一个过滤器(网上大神写好的)

package com.atdk.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * 解决get和post请求 全部乱码的过滤器
 */
public class GenericEncodingFilter implements Filter {

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //处理response的字符编码
        HttpServletResponse myResponse = (HttpServletResponse) response;
        myResponse.setContentType("text/html;charset=UTF-8");

        // 转型为与协议相关对象
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        // 对request包装增强
        HttpServletRequest myrequest = new MyRequest(httpServletRequest);
        chain.doFilter(myrequest, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

}

//自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {

    private HttpServletRequest request;
    //是否编码的标记
    private boolean hasEncode;

    //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
    public MyRequest(HttpServletRequest request) {
        super(request);// super必须写
        this.request = request;
    }

    // 对需要增强方法 进行覆盖
    @Override
    public Map getParameterMap() {
        // 先获得请求方式
        String method = request.getMethod();
        if (method.equalsIgnoreCase("post")) {
            // post请求
            try {
                // 处理post乱码
                request.setCharacterEncoding("utf-8");
                return request.getParameterMap();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else if (method.equalsIgnoreCase("get")) {
            // get请求
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (!hasEncode) { // 确保get手动编码逻辑只运行一次
                for (String parameterName : parameterMap.keySet()) {
                    String[] values = parameterMap.get(parameterName);
                    if (values != null) {
                        for (int i = 0; i < values.length; i++) {
                            try {
                                // 处理get乱码
                                values[i] = new String(values[i]
                                        .getBytes("ISO-8859-1"), "utf-8");
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                hasEncode = true;
            }
            return parameterMap;
        }
        return super.getParameterMap();
    }

    //取一个值
    @Override
    public String getParameter(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        if (values == null) {
            return null;
        }
        return values[0]; // 取回参数的第一个值
    }

    //取所有值
    @Override
    public String[] getParameterValues(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        return values;
    }
}

3.在web.xml中配置此过滤器即可

以上是本人学习狂胜说所做笔记,参考了狂神的博客,谢谢狂神。

你可能感兴趣的:(SpringMVC,过滤器,乱码,java,spring,servlet)