1 action方法的返回值
package com.zhiyou100.action02;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/test21")
public class Test21 {
@RequestMapping("/m1.do")
public ModelAndView method01(int n){
ModelAndView mav=new ModelAndView();
mav.addObject("message","m1:n="+n);
mav.setViewName("jsp01/test02_success");
return mav;
}
@RequestMapping("/m21.do")
public String method021(int n,Model m){
m.addAttribute("message","m21:n="+n);
return "jsp01/test02_success";
}
@RequestMapping("/m22.do")
public String method022(int n,Model m){
m.addAttribute("message","m22:n="+n);
return "redirect:/jsp01/test02_success.jsp";
}
@RequestMapping("/m31.do")
public void method031(int n){
System.out.println("m31执行了:::n="+n);
}
@RequestMapping("/m32.do")
public void method032(int n,HttpServletResponse resp)throws Exception{
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("m32:::请求参数n="+n);
}
}
- 注意:如果返回值是void 并且没有通过response拼凑页面时:响应资源的路径默认为action同名的url
2 通过mvc标签自动注册注解形式的处理器映射器和处理器适配器
2.1 在springmvc的核心配置文件中 引入mvc标签的命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
2.2 通过mvc标签 自动注册注解形式的两个组件
<mvc:annotation-driven/>
3 全站编码过滤器
<filter>
<filter-name>characterFilter</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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterFilter</filter-name>
<url-pattern>*.do</url-pattern>
<dispatcher>ERROR</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
4 参数是日期时处理方式
4.0 不设置时:报错400
@RequestMapping("/m1.do")
public String method01(int n,Date date,Model m){
m.addAttribute("message", "m1.do:::直接用Date接受:::"+n+":::"+date.toLocaleString());
return "jsp01/test02_success";
}
<a href="<c:url value='/test23/m1.do?n=32&date=1234-11-12'/>">请求/test23/m1.do?n=32&date=1234-11-12</a><br/>
<a href="<c:url value='/test23/m2.do?n=32&date=1234/11/12'/>">请求/test23/m2.do?n=32&date=1234/11/12</a><br/>
<a href="<c:url value='/test23/m2.do?n=32&date=1234/11/12 11:12:13'/>">请求/test23/m2.do?n=32&date=1234/11/12 11:12:13</a><br/>
<a href="<c:url value='/test23/m3.do?n=32&dateStr=1234-11-12 11:12:13'/>">请求/test23/m3.do?n=32&dateStr=1234-11-12 11:12:13</a><br/>
<a href="<c:url value='/test23/m4.do?n=32&date=1234-11-12 11:12:13'/>">请求/test23/m4.do?n=32&date=1234-11-12 11:12:13</a><br/>
<a href="<c:url value='/test23/m5.do?n=32&date=1234-11-12 11:12:13'/>">请求/test23/m5.do?n=32&date=1234-11-12 11:12:13</a><br/>
<a href="<c:url value='/test23/m6.do?n=32&date=1234-11-12 11:12:13'/>">请求/test23/m6.do?n=32&date=1234-11-12 11:12:13</a><br/>
4.1 解决方案1:参数格式固定为:yyyy/MM/dd HH:mm:ss::sping日期的默认格式
@RequestMapping("/m2.do")
public String method02(int n,Date date,Model m){
m.addAttribute("message", "m2.do:::直接用Date接受:::"+n+":::"+date.toLocaleString());
return "jsp01/test02_success";
}
4.2 解决方案2:使用字符串接受:通过simpldateformat自己解析
@RequestMapping("/m3.do")
public String method03(int n,String dateStr,Model m)throws Exception{
Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
m.addAttribute("message", "m3.do:::使用string接受:::"+n+":::"+date.toLocaleString());
return "jsp01/test02_success";
}
4.3 解决方案3:通过注解@DateTimeFormat
@RequestMapping("/m4.do")
public String method04(int n,@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")Date date,Model m)throws Exception{
m.addAttribute("message", "m4.do:::使用@DateTimeFormat注解的date接受:::"+n+":::"+date.toLocaleString());
return "jsp01/test02_success";
}
4.4 解决方案4: 通过注解@InitBinder定义自定义日期解析器
@RequestMapping("/m5.do")
public String method05(int n,Date date,Model m)throws Exception{
m.addAttribute("message", "m5.do:::使用@InitBinder来自定义日期参数类型的解析器的date接受:::"+n+":::"+date.toLocaleString());
return "jsp01/test02_success";
}
@InitBinder
public void setDateBinder(HttpServletRequest req,ServletRequestDataBinder binder)throws Exception{
req.setCharacterEncoding("UTF-8");
CustomDateEditor cde=new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), false);
binder.registerCustomEditor(java.util.Date.class, cde);
}
只能影响当前类
4.5 解决方案5: 通过接口Converter定义全局的日期解析器
package com.zhiyou100.action02;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
public class MyDateConverter implements Converter<String, Date>{
public Date convert(String str) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return sdf.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
- 在springmvc的核心配置文件中创建FormattingConversionServiceFactoryBean 管理定义的解析器bean
<bean id="myDateConverServiceBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" >
<property name="converters">
<set>
<bean class="com.zhiyou100.action02.MyDateConverter"/>
</set>
</property>
</bean>
- 在springmvc的核心配置的mvc自动注册处理器映射器和处理器适配器的标签中添加conversion-service属性
<mvc:annotation-driven conversion-service="myDateConverServiceBean"/>
5 url模板映射
把请求参数伪装为url的路径
@RequestMapping("/m1.do")
public ModelAndView method01(int age,String name,float score){
ModelAndView mav=new ModelAndView();
mav.addObject("message","m1:"+age+":"+name+":"+score);
mav.setViewName("jsp01/test03_success");
return mav;
}
@RequestMapping("/m2/{age}/{name}.do")
public ModelAndView method02(@PathVariable("age")int sage,@PathVariable("name")String sname,float score){
ModelAndView mav=new ModelAndView();
mav.addObject("message","m2:"+sage+":"+sname+":"+score);
mav.setViewName("jsp01/test03_success");
return mav;
}
@RequestMapping("/m3/{sage}/{sname}.do")
public ModelAndView method03(@PathVariable int sage,@PathVariable String sname,float score){
ModelAndView mav=new ModelAndView();
mav.addObject("message","m3:"+sage+":"+sname+":"+score);
mav.setViewName("jsp01/test03_success");
return mav;
}
<h1>1:url模板映射</h1>
<a href="<c:url value='/test31/m1.do?name=韩梅梅&age=18&score=11.5'/>">/test31/m1.do?name=韩梅梅&age=18&score=11.5</a><br/>
<a href="<c:url value='/test31/m2/19/hmm.do?score=11.5'/>">/test31/m2/19/hmm.do?score=11.5</a><br/>
<a href="<c:url value='/test31/m3/39/韩梅梅.do?score=33.5'/>">/test31/m3/39/韩梅梅.do?score=33.5</a><br/>
6 json数据的传递
6.0 json概念
json是一种js可以直接解析数据格式 类似于对象可以封装数据
json格式:{属性名:属性值,属性名:属性值,属性名:属性值}
属性名必须写在引号中
属性值可以是:number+string+boolean+null+数组+json对象
注意:json::json是js的内容:js与java后台数据交互 只能通过ajax
6.1 响应是json
<a href="javascript:test21();">响应是json:通过jquery的get方法实现</a><br/>
<script type="text/javascript">
function test21(){
//jQuery.get(url, [data], [callback], [type])
$.get("<c:url value='/test32/m1.do'/>","sid=1",function(data){
alert(data);
alert(data.sid+"::"+data.sname+"::"+data.sage+"::"+data.score+"::"+data.sex);
},"json");
}
</script>
<a href="javascript:test22();">响应是json:通过jquery的ajax方法实现</a><br/>
<script type="text/javascript">
function test22(){
//jQuery.ajax([options])
//async:是否异步 默认: true
//cache:是否使用缓存 默认: true
//contentType:请求数据的格式:默认: "application/x-www-form-urlencoded"
//data:请求参数
//dataType:期待响应数据的类型
//success:成功后的回调函数
//url:请求路径
//type:请求方式 默认GET
$.ajax({
async:true,
cache:false,
data:"sid=2",
"dataType":"json",
"url":"<c:url value='/test32/m1.do'/>",
success:function(data){
alert(data);
alert(data.sid+"::"+data.sname+"::"+data.sage+"::"+data.score+"::"+data.sex);
}
});
}
</script>
@RequestMapping("/m1.do")
@ResponseBody
public Student method01(int sid){
return new Student(sid, "hmm", "123", "女", 11, true, 11.6f);
}
6.2 请求是json
<a href="javascript:test23();">请求是json串:通过jquery的post方法实现::通过get和post方法无法实现请求是json::415响应码</a><br/>
<script type="text/javascript">
//
function test23(){
//jQuery.get(url, [data], [callback], [type])
$.post("<c:url value='/test32/m2.do'/>",'{"sid":11,"sname":"韩梅梅","sage":12,"sdy":true,"score":14.5}',function(data){
alert(data);
},"text");
}
</script>
<a href="javascript:test24();">请求是json串:通过jquery的ajax方法实现</a><br/>
<script type="text/javascript">
function test24(){
//jQuery.ajax([options])
//async:是否异步 默认: true
//cache:是否使用缓存 默认: true
//contentType:请求数据的格式:默认: "application/x-www-form-urlencoded"
//data:请求参数
//dataType:期待响应数据的类型
//success:成功后的回调函数
//url:请求路径
//type:请求方式 默认GET
$.ajax({
async:true,
cache:false,
data:'{"sid":11,"sname":"韩梅梅","sage":12,"sdy":true,"score":14.5}',
contentType:"application/json;charset=utf-8",//通过contentType来指定请求数据的格式
"dataType":"text",
"url":"<c:url value='/test32/m2.do'/>",
success:function(data){
alert(data);
},
type:"post" //请求时json时 请求方式必须是post请求
});
}
</script>
@RequestMapping("/m2.do")
public void method02(@RequestBody Student stu,HttpServletResponse resp)throws Exception{
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("请求时json::"+stu);
}
6.3 请求响应都是json
<a href="javascript:test25();">请求是json串 响应是json:通过jquery的ajax方法实现</a><br/>
<script type="text/javascript">
function test25(){
$.ajax({
async:true,
cache:false,
data:'{"sid":11,"sname":"韩梅梅","sage":12,"sdy":true,"score":14.5,"sex":"女"}',
contentType:"application/json;charset=utf-8",//通过contentType来指定请求数据的格式
"dataType":"json",
"url":"<c:url value='/test32/m3.do'/>",
success:function(data){
alert(data);
alert(data.sid+"::"+data.sname+"::"+data.sage+"::"+data.score+"::"+data.sex);
},
type:"post" //请求时json时 请求方式必须是post请求
});
}
</script>
@RequestMapping("/m3.do")
@ResponseBody
public Student method03(@RequestBody Student stu){
stu.setSage(stu.getSage()+1);stu.setScore(stu.getScore()+1);
stu.setSid(stu.getSid()+1);
return stu;
}
6.4 注意
- 如果通过mvc标签自动引入注解的处理器和适配器:可以使用json
<mvc:annotation-driven/>
- 如果通过显式配置注解的处理映射器和处理器适配器:报错415
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
- 报错:415:数据格式不支持:需要在处理器适配器中添加json的解析器
- 解决方案:在处理器适配器中配置json解析器
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
7 数据回显
7.1 概念
注册页面进行注册时:成功 跳转到登录页面
失败时 跳转到注册页面:::再次回到注册页面::页面刷新了 上次填写的所有内容都要重新填写::客户体验行很差
再次回到当前页面:希望保留表单的所有数据:::数据回显
7.2 参数是单值参数::需要手动把数据添加到request域中
<h1>3:数据回显</h1>
<c:if test="${not empty requestScope.message}">
提示信息:${requestScope.message}<br/>
</c:if>
<form action="<c:url value='/test33/m1.do'/>" method="post">
sid:<input type="text" name="sid" value="${requestScope.stu.sid}"/><br/>
sname:<input type="text" name="sname" value="${requestScope.stu.sname}"/><br/>
sage:<input type="text" name="sage" value="${requestScope.stu.sage}"/><br/>
sex: 女<input type="radio" name="sex" value="女"/> | 男<input type="radio" name="sex" value="男"/><br/>
sdy: 党员<input type="radio" name="sdy" value="true"/> | 群众<input type="radio" name="sdy" value="false"/><br/>
score:<input type="text" name="score" value="${requestScope.stu.score}"/><br/>
spwd:<input type="text" name="spwd" value="${requestScope.stu.spwd}"/><br/>
<input type="submit" value="方法参数是单值参数:注册"/>
</form>
<script type="text/javascript">
$(function(){
//获取request域中sex值
var sex="${requestScope.stu.sex}";
//判断哪个radio的 值为此值 让其为选中状态
$.each($("input[type='radio'][name='sex']"),function(i,n){
if(n.value==sex){
n.checked="checked";
}
});
alert(sex);
});
</script>
@RequestMapping("/m1.do")
public String method01(int sid,String sname,String sex,String spwd,boolean sdy,int sage,float score,Model model){
model.addAttribute("stu",new Student(sid, sname, spwd, sex, sage, sdy, score));
System.out.println("注册失败!用户名已存在!");
model.addAttribute("message", "注册失败!用户名已存在!");
return "jsp01/test03_index";
}
7.3 参数是对象类型:springmvc默认把对象装入request域中
<form action="<c:url value='/test33/m2.do'/>" method="post">
sid:<input type="text" name="sid" value="${requestScope.student.sid}"/><br/>
sname:<input type="text" name="sname" value="${requestScope.student.sname}"/><br/>
sage:<input type="text" name="sage" value="${requestScope.student.sage}"/><br/>
sex: 女<input type="radio" name="sex" value="女"/> | 男<input type="radio" name="sex" value="男"/><br/>
sdy: 党员<input type="radio" name="sdy" value="true"/> | 群众<input type="radio" name="sdy" value="false"/><br/>
score:<input type="text" name="score" value="${requestScope.student.score}"/><br/>
spwd:<input type="text" name="spwd" value="${requestScope.student.spwd}"/><br/>
<input type="submit" value="方法参数是对象类型:注册"/>
</form>
@RequestMapping("/m2.do")
public String method02(Student stu,Model model){
System.out.println("注册失败!用户名已存在!");
model.addAttribute("message", "注册失败!用户名已存在!");
return "jsp01/test03_index";
}