2.SpringMVC中的跳转和参数接收

SpringMVC中的跳转和参数接收

一,servlet跳转方式

1.forward:请求转发

​ 服务器内部跳转,跳转url不变,跳转可以使用request作用域传递数据

2.redirect:请求重定向

在客户端内跳转,跳转之后url变化,不能传递数据

二,SpringMVC跳转方式

1.在相同的Controller内跳转

1.forward跳转到页面

默认就是forward跳转 语法: return "页面逻辑名"或者 return "forward:xxx/xxx"

例如:

    @Controller("test")
    //加在类上以后先访问类
    @RequestMapping(value = "HelloGroup")
    public class TestController {
        @RequestMapping(value = "Sayhello")
        public  String SayHello(){
            System.out.println("TestController.SayHello");
            return "index";
        }
        @RequestMapping(value = "SayHello2")
        public String SayHello2(){
            System.out.println("TestController.SayHello2");
            return "forward:/HelloGroup/Sayhello";
        }

访问URL如下

http://localhost:8080/SpringMVC01_war_exploded/HelloGroup/SayHello2

控制台打印如下

    TestController.SayHello2
    TestController.SayHello

可见访问路径

2.redirect跳转到页面

使用springmvc提供redirect:关键字进行重定向页面跳转
语法: return "redirect:目的视图全命名" (包括/和后缀)
注意: 使用redirect跳转页面不会经过试图解析器,因为指定了目的视图,无需组装

例如:

@RequestMapping(value = "RedirectHello")
public String RedirectHello(){
    System.out.println("TestController.RedirectHello");
    return "redirect:/index.jsp";
}

使用灵活可以自由搭配

2.在不同的Controller内跳转

使用和上面的完全一致,只不过是把逻辑地址换为了其他的Controller而已,非常简单

三,SpringMVC中参数接收

(注)这段主要是从JSP-->SpringMVC

1.普通JDK类型,包括util日期

SpringMVC传送单个或者多个参数的方法很简单,只需要把Controller 的方法形参对应上列表即可,还会进行类型转换,像Spring 在某些时候还需要自己些类型转换器,比如Util的Date

例如:

@Controller
@RequestMapping(value = "Param")
public class ParamController {
    @RequestMapping(value = "JdkParam")
    public String JDKParam(String name, Integer age, double price, Date bir){
        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("price = " + price);
        System.out.println("bir = " + bir);
        return "index";
    }

url如下:

# GET 方式传递参数http://localhost:8080/SpringMVC01_war_exploded/Param/JdkParam?name=SY&price=1.1&bir=2020/1/1&age=11

控制台打印如下:

    name = SY
    age = 11
    price = 1.1
    bir = Wed Jan 01 00:00:00 CST 2020

2.数组类型

只需要请求的每个key相同(重要)就代表了传送给一个数组

例如:

@RequestMapping("Arry")
public String ArryParam(String[]Param){
    for (String p:Param
         ) {
        System.out.println("p = " + p);
    }
return "index";
}

url如下:

# GET 方式传递参数http://localhost:8080/SpringMVC01_war_exploded/Param/Arry?Param=A&Param=b&Param=C&Param=D

打印:

    p = A
    p = b
    p = C
    p = D

3.自定义类型

对于拥有大量数据需要传送就不太可能使用Url,所以就使用对象传送,对象传送SpringMVC会自动匹配成员变量

例如:

我的自定义对象User

public class User {
    String name;
    String id;
    String age;
    //提供GET/SET方法和toStirng
    xxx
}

控制器方法

@RequestMapping(value = "ObjectParam")
public String ObjectParam(User user){
    System.out.println(user.toString());
    return "index";
}

url为:

# GET 方式传递参数http://localhost:8080/SpringMVC01_war_exploded/Param/ObjectParam?name=SY&id=32&age=99

打印为:

    User{name='SY', id='32', age='99'}

4.集合类型

SpringMVC不支持使用形参列表直接传送参数

SpringMVC推荐使用VO传送集合对象方法和上面自定义类型一样,不过多操作了,只需要把集合类型作为自定义类型的参数即可

5.表单传送参数

需要值得注意的表单传送的数据和url传送数据方式类似,所以如果需要传送自定义对象,数组,集合只需要把表单中的name作为url的KEY即可

例如(以个别数据和数组为例)

个别数据:

<form action="Param/JdkParam" method="POST">
    id:<input type="text" name="id"><br>
    name:<input type="text" name="name"><br>
    age:<input type="text" name="age"><br>
    price:<input type="text" name="price"><br>
    <input type="submit" value="confirm">
</form>

接受参数代码在【三.1】中

结果为,可以看见有乱码下面解决

    name = ?±±è??
    age = 123
    price = 1.1
    bir = null

数组:

<form action="Param/Arry" method="POst">
    id:<input type="text" name="Param"><br>
    name:<input type="text" name="Param"><br>
    age:<input type="text" name="Param"><br>
    price:<input type="text" name="Param"><br>
    <input type="submit" value="confirm">
</form>

接受参数代码在【三.2】中

结果为

    p = 32
    p = ?±±è??
    p = 12
    p = 2.0

四,POST乱码问题解决方式

在学习servlet之前也有乱码情况,通过设置请求域编码,过滤器等方式,在SpringMVC也差不多。

在tomcat8以前版本的GET方式会出现乱码,原因是在web.xml配置文件中URIEncoding是Unicode现在设置为UTF-8即可

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

1.Filter

过滤器

public class EncodingFilter implements Filter {
    private String code;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
       this.code= filterConfig.getInitParameter("encoding");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding(this.code);
        response.setCharacterEncoding(this.code);
        chain.doFilter(request,response);
    }

    @Override
    public void destroy() {
    }
}

web.xml

<filter>
  <filter-name>character</filter-name>
  <filter-class>Filter.EncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>GBK</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>character</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

2.Spring提供的过滤器

web.xml 注意param-name参数不要填错了

<filter>
  <filter-name>charset</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>charset</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

五,SpringMVC中的数据传递

(注)这段从SpringMVC-->Jsp

1.JSTL和EL

之前没怎么关注这个,现在发现还是比较重要,重新学习和总结了下

1.JSTL

< c:set>

< c:set> 等同于JSP中的 session的setAttribute() 方法

使用方法:<c:set var=”名字” value=”值”/>

< c:out>

< c:out> 等同于 JSP中的 <%= %>

使用方法:<c:out value=”需要输出的值”>

< c:remove>

< c:remove> 和c:set标签正好相反,c:set标签是设置setAttrbute 这个标签则是 删除 Attrbute中设置的值 等同于 session中的removeAttrbute()方法

使用方法:<c:remove var=”名字”/>

< c:if>

< c:if> 等同于 java 中的 if 语句

使用方法:<c:if test=”条件”> 满足条件执行的JSP代码 < /c:if>

< c:catch>

< c:catch> 类似于 java 中的 try

使用方法:<c:catch var=”名字”>JSP代码< /c:catch>

< c:choose> < c:when>< c:otherwise>

< c:choose> 和 < c:when> 类似于 java 中的 switch 和 case

使用方法:(c:choose中可以有多个c:when标签)

<c:choose>
<c:when test=”条件”>处理</c:when>
<c:when test=”条件”>处理</c:when>
<c:otherwise>处理</c:otherwise>    
</c:choose>

< c:otherwise> 等同于 java switch 中的 default

< c:import>

检索一个绝对或相对 URL,然后将其内容暴露给页面

< c:forEach> 和 < c:forTokens>

类似于JAVA中的 FOR循环 和 FOREACH循环

forEach 和forTokens 语法格式

<c:forEach
    items="<object>"
    begin="<int>"
    end="<int>"
    step="<int>"
    var="<string>"
    varStatus="<string>">
    ...

属性

< c:forEach>标签有如下属性:

属性 描述 是否必要 默认值
items 要被循环的信息
begin 开始的元素(0=第一个元素,1=第二个元素) 0
end 最后一个元素(0=第一个元素,1=第二个元素) Last element
step 每一次迭代的步长 1
var 代表当前条目的变量名称
varStatus 代表循环状态的变量名称

< c:forTokens>标签与< c:forEach>标签有相似的属性,不过< c:forTokens>还有另一个属性:

属性 描述 是否必要 默认值
delims 分隔符
< c:redirect>

类似于service中的重定向

使用方法:<c:redirect url=”#地址”/>

2.EL

EL表达式定义规则:以 $ 开头 内容写在 {} 中 例: ${test}

操作符 描述
. 访问一个Bean属性或者一个映射条目
[] 访问一个数组或者链表的元素
( ) 组织一个子表达式以改变优先级
+
- 减或负
*
/ or div
% or mod 取模
== or eq 测试是否相等
!= or ne 测试是否不等
< or lt 测试是否小于
> or gt 测试是否大于
<= or le 测试是否小于等于
>= or ge 测试是否大于等于
&& or and 测试逻辑与
|| or or 测试逻辑或
! or not 测试取反
empty 测试是否空值

如果要动态取值 可以使用[]

比如:${session.user[param]}

1.EL表达式查找顺序(都是针对Attrbute()):

如果使用类似于 ${username} 没有指定哪个范围

那么它会以:

  1. Page
  2. Request
  3. Session
  4. Application

为顺序来进行查找,加入中途找到了 username 那么就会返回值 如果一路没找到 返回 null

2.EL表达式的隐性变量:
隐含对象 描述
pageScope page 作用域
requestScope request 作用域
sessionScope session 作用域
applicationScope application 作用域
param Request 对象的参数,字符串
paramValues Request对象的参数,字符串集合
header HTTP 信息头,字符串
headerValues HTTP 信息头,字符串集合
initParam 上下文初始化参数
cookie Cookie值
pageContext 当前页面的pageContext

param和paramValues

param对象用于获取请求参数的某个值,它是Map类型,与request.getParamter()方法相同,如:url传送的数据

例:我们想要获得GET或则POST传递过来的name参数,在以前我们只能使用:

request.getParameter(name);

使用EL表达式可代替为:

${param.name}

如果一个请求参数有多个值,可以使用paramValues对象来获取请求参数的所有值

例:num请求参数有多个值

<form action="${pageContext.request.contextPath}/param.jsp">
		num1:<input type="text" name="num1"><br /> 
		num2:<input type="text" name="num"><br /> 
		num3:<input type="text" name="num"><br /> <br />
		<input type="submit" value="提交" />&nbsp;&nbsp;
		<input type="submit" value="重置" />
		<hr>
		num1:${param.num1}<br />
		num2:${paramValues.num[0]}<br />
		num3:${paramValues.num[1]}<br />
	</form>

参考:

EL表达式中的param和paramValues对象

JSTL和EL的使用

JSP 表达式语言_w3cschool

2.SpringMVC数据传送机制

数据存储位置 数据如何获取 数据如何展示在JSP
Servlet request,session,application EL EL+JSTL
Struts2 request,session,application EL EL+JSTL
SpringMVC request,session,application EL EL+JSTL

1.存储数据的作用域和SpringMVC获取作用域

1.存储数据

跳转方式

forward:使用Request作用域或者SpirngMVC提供的Model对象(对Request的封装)

redire: session,application(一直保存到程序消亡,少用),通过url问号传送数据

2.获取作用域(重要)

直接在Controller里面声明HttpServletRequest,HttpServletResponse变量即可

public class ScopeController {
    public String finfAll(HttpServletRequest request, HttpServletResponse response){
 		xxx   
        return "xxx";
    }
}

3.数据传递实例

1.forward

1.传递零散数据

Controller:

/*
* 实例一:使用request传递零散数据
* 只需要使用request.setAttribute()即可
* */
String name="sy";
Integer id=32;
request.setAttribute("name",name);
request.setAttribute("id",id);

JSP:

<!--使用EL表达式中requestScope接收数据-->
<h3>测试request作用域传送一般数据</h3>
name: ${requestScope.name}<br>
id: ${requestScope.id}<br>
2.传送对象

Controller:

/**
 * 实例二:request作用域传送对象
 */
User user=new User();
user.setName("SY1");
user.setId("132");
request.setAttribute("User",user);

JSP:

<h3>测试request作用域对象</h3>
name:${requestScope.User.name}
id:${requestScope.User.id}
3.传送集合

Controller:

/**
 *实例三:request作用域传送集合
 * Arrays.asList用于快速组成集合
 */
User user1=new User();
user1.setName("SY2");
user1.setId("232");
List<User> Users= Arrays.asList(user,user1);
request.setAttribute("Users",Users);

JSP:

<!--遍历方法要搭配JSTL,要记住JSP用来展示数据,不要做逻辑处理-->
<h3>测试request作用传送集合</h3>
<c:forEach items="${requestScope.Users}" var="S">
    id:${S.id} & name:${S.name}<br>

2.redirect

1.传送零散数据

Controller:

/**
 *redirect方式使用URL传送数据
 *  URLEncoder.encode解决中文编码问题
 *  request.getSession().setAttribute()设定k-v
 */
String name="山芋";
String id="32";
 return "redirect:/TestScope.jsp?name="+ URLEncoder.encode(name,"UTF-8") +"&id="+id;

JSP:

<!--接受url传送的数据-->
<h3>测试redirect传送数据</h3>
name:${param.name}<br>
id:${param.id}
2.使用ssesion传送

Controller:

String name="山芋";
String id="32";
request.getSession().setAttribute("name",name);
request.getSession().setAttribute("id",id);

JSP:

<!--接受session的数据-->
<h3>测试redirect-session传送数据</h3>
name:${sessionScope.name}<br>
id:${sessionScope.id}
3.使用ssesion传送对象

ssession有”传什么送什么“的特性

Controller:

User user=new User();
user.setName("SY");
user.setId("32");
request.getSession().setAttribute("user",user);

JSP:

<h3>测试传送对象</h3>
name:${sessionScope.user.name}===id:${sessionScope.user.id}

集合也是一样的不过多赘述

现在再次回去看SpringMVC的数据传送机制,更加理解

posted on 2021-08-10 16:34  NathenJames  阅读(238)  评论(0编辑  收藏  举报