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} 没有指定哪个范围
那么它会以:
- Page
- Request
- Session
- 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="提交" />
<input type="submit" value="重置" />
<hr>
num1:${param.num1}<br />
num2:${paramValues.num[0]}<br />
num3:${paramValues.num[1]}<br />
</form>
参考:
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的数据传送机制,更加理解