springmvc_02

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 {
	
	//action方法的返回值类型1:modelandview::设置request域属性+跳转的资源的路径
	@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;
	}
	//action方法的返回值类型2:String::设置跳转的逻辑路径
	@RequestMapping("/m21.do")
	public String method021(int n,Model m){
			m.addAttribute("message","m21:n="+n);
			return "jsp01/test02_success";// /java43_05_springmvc03/jsp01/test02_success.jsp
	}
    //action方法的返回值类型2:String::设置跳转的逻辑路径
	@RequestMapping("/m22.do")
	public String method022(int n,Model m){
			m.addAttribute("message","m22:n="+n);
			return "redirect:/jsp01/test02_success.jsp";//重定向
	}
	
	//action方法的返回值类型3:void::方法名默认作为视图名/自己拼凑页面
	@RequestMapping("/m31.do")
	public void method031(int n){
			System.out.println("m31执行了:::n="+n);
			//返回void 必须拼凑页面
	}
	@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

image-20230110145011142

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标签 自动注册注解形式的处理器映射器和处理器适配器 -->
<mvc:annotation-driven/>
<!-- 完全等价于
  <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
  <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
  -->

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 指定不管怎么请求action都需要过此过滤器 -->
    <dispatcher>ERROR</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

4 参数是日期时处理方式

4.0 不设置时:报错400

  • action
//参数是日期类型:如果使用Date直接接受:
//错误:400 客户端端请求参数无法被action的方法参数接受
@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";
}
  • jsp
<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日期的默认格式

//参数是日期类型方式1::日期字符串格式必须是yyyy/MM/dd HH:mm:ss
@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自己解析

//参数是日期类型方式2::使用字符串接受 使用simpledateformat进行转换
@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

//参数是日期类型   方式3::使用字符串接受 使用simpledateformat进行转换
//使用@DateTimeFormat  适用于spring版本4.3+
@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定义自定义日期解析器

//参数是日期类型   方式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";
}
//自定义action的方法参数解析器
@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定义全局的日期解析器

  • 创建一个类实现接口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 -->
<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标签 自动注册注解形式的处理器映射器和处理器适配器 -->
<mvc:annotation-driven conversion-service="myDateConverServiceBean"/>

5 url模板映射

把请求参数伪装为url的路径
  • action
@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;
}
//使用url模板映射:url中包含两个参数:age和name
@RequestMapping("/m2/{age}/{name}.do")
//@PathVariable("age")int sage使用 方法参数sage接受url中age的值
//@PathVariable("name")String sname使用 方法参数sname接受url中name的值
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;
}

//使用url模板映射:url中包含两个参数:age和name
@RequestMapping("/m3/{sage}/{sname}.do")
//@PathVariable int sage使用 方法参数sage接受url中sage的值
//@PathVariable String sname使用 方法参数sname接受url中sname的值
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;
}
  • jsp
<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

  • jsp
<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>
  • action
@RequestMapping("/m1.do")
//响应是json
@ResponseBody //响应的数据不是逻辑路径::而是Student类型对象对应的json串给ajax
public Student method01(int sid){
    return new Student(sid, "hmm", "123", "女", 11, true, 11.6f);
}

6.2 请求是json

  • jsp
<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>
  • action
@RequestMapping("/m2.do")
//@RequestBody Student stu 使用stu对象来接受 请求参数json串中的数据
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

  • jsp
<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>
  • action
@RequestMapping("/m3.do")
//响应是json
@ResponseBody //响应的数据不是逻辑路径::而是Student类型对象对应的json串给ajax
//@RequestBody Student stu 使用stu对象来接受 请求参数json串中的数据
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">
    <!-- 配置json解析器 -->
    <property name="messageConverters">
        <list>
            <!-- json转换器 -->
            <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域中

  • jsp
<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>
  • action
@RequestMapping("/m1.do")
//方法参数是单值参数时:需要手动把数据装入requeest域中
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域中

  • jsp
<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>
  • action
@RequestMapping("/m2.do")
//方法参数是对象时:springmvc 默认把此对象装入request域中:域属性的名字为类名首字母小写
public String method02(Student stu,Model model){
    //model.addAttribute("student", stu)  springmvc已经做了这件事
    System.out.println("注册失败!用户名已存在!");
    model.addAttribute("message", "注册失败!用户名已存在!");
    return "jsp01/test03_index";
}
  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值