spring-mvc

1.初始内容

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

//在地址中通过如下方式访问
//http://localhost -IP地址标识网络中被访问的哪台计算机:
//:8080  -端口号标识你要访问这台计算机上哪一个应用程序(我们计算机中是不是有很多的应用程序 端口就是一个唯一标识)/
//(那在:8080后面我们有一个项目)CGB-SPRING-MVC-01   -我们有一个项目 就表示你要访问tomcat中哪一个项目
//doSayHello.do 这个项目中是不是会有很多资源  就意味着有很多控制层对象 你要访问哪一个对象呢 是不是就是这个地址  doSayHello.do
//通过这个地址 /doSayHello.do 来看 前面这部分 你们知道是什么吗
//@RequestMapping("/") 中的“/”  就是 /doSayHello.do中前面的“/”
//http://localhost:8080/CGB-SPRING-MVC-01/doSayHello.do

/**
 * 把这个对象交给spring去管理  spring是要扫描这个包下面的类
 * 但是呢说它不是说要管理所有的类 它只管理那些类呢  有特定注解修饰或是描述的这些类
 * 才由spring来管理
 *spring会把这个对象存储到容器  现在它的key是什么  默认情况是类的名称首字母小写
 *
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/") //@RequestMapping 除了可以描述我们的方法 还可以描述类
public class HelloController {
	
	/**
	 * ModelAndView 为Spring MVC提供的一个API对象
	  * 此对象主要用来封装视图对象以及这个视图对象要呈现的数据信息
	  * 测试字体大小
	 * @return
	 */
	
	//这个方法写了之后 如何用我们的客户端能访问到它呢
	//我们一般需要去定义一下这个方法的一个映射
	//我们通过哪一个url 可以访问到这个方法 我们可以这么来写
	//
	//@RequestMapping("/doSayHello") //请求映射  里面可以随便写  但是建议和方法名相同
	@RequestMapping("doSayHello") //这个doSayHello后面可以有.do  也可以没有 但是你在地址栏请求访问的时候必须有这个.do 因为我们在哪个xml中配置的请求映射是.do结尾吧
	//假如我们这个类中有好多的方法 那么都要去定义一个映射
	//那么建议把映射路径中的这个“/” 写到哪里去 写到上面去
	//url 对应的方法对象会存储到map map中会定义一种这样的关系
	//这个关系是这样的   这个方法是谁 是不是我们这个类中的方法
	//它会基于url 找到你这个类对象  并找到你这个类对象的方法  然后执行你这个方法
	public ModelAndView doSayHello() {
		
		//这个modelAndView就是spring提供的一个对象
		//这个对象要封装什么信息 一个是普通的值 还有一个是视图吧
		//1.构建ModelAndView对象(作用 封装响应数据和视图信息)
		ModelAndView mv = new ModelAndView();
		//封装客户端页面要呈现的相关数据信息
		
		//mvc 底层会将model(底层实现是一个map)中存储的key/value存储在request作用域中
		//这个存储的时候它是怎么样存储的呢 
		//其实在底层调用的是这个方法 request.setAttribute("key","value")
		//那我们取的时候 从request作用域中去取就可以了
		mv.addObject("message", "hello cgb1806");//存model接口对应的map对象 还会把mapd对象放在request作用域
		//3.封装要呈现的页面视图信息
		
		//设置我们的视图名称 你要写个hello  此名字会交给视图解析器进行解析
		//测试字体大小
		
		mv.setViewName("hello");
		//WEB-INF/pages/hello.jsp
		//那到这个页面 它底层执行请求的是转发
		return mv; //底层会对返回的view进行解析,然后转发到对应的JSP页面
	}

}

2.请求数据封装

 package controller;

import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/req/")
//多个URL路径可以映射到同意个处理器的功能处理方法 如下:
//@RequestMapping(value= {"/doSayHello","/user/doSayWelcome"})
public class RequestHandleController {
	
	@RequestMapping("doReqUrlMap01")
	@ResponseBody
	public String doReqUrlMap01() {
		//直接返回字符串会被当做视图去处理  需要在方法上添加相应注解@RequestBody
		//将你这个方法的返回值以字符串的形式呈现 而不是页面
		return "rquest url mapping";
	}
	
	
	
	//----------------------------请求参数处理----------------------------------//
	//请求参数处理
	//---------------------------第一种  === 标准servlet API----------------------//
	/**
	 * 
	 * 在spring中所有的控制层方法当中都可以写上这个值
	 * 假如没有这个HttpServletRequest那肯定是Tomcat环境没有添加进来
	 * 
	 * 在这个方法的参数中 你可以写任意的servlet API  在这里只写了一个Request 
	 *还可以写HttpServletResponse   或者HttpSession
	 *所以的Servlet API  你都可以放在这个方法里面
	 *
	  *  在这里  请问这个 HttpServletRequest 请求对象 是谁来创建的
	 *  是由 Tomcat 来创建的  当我们的请求到我们的服务器之后呢  我们服务器的会创建
	 *  这么一个对象  通过这么个对象来封装请求中的信息 所以可以通过这个请求对象中
	 *  来获取我们请求信息中的参数数据,那这个就叫做标准Servlet API 的方式来获取请求数据
	 *  
	 *  
	 *
	 */
	@RequestMapping("doReqParam02")
	//提示:@ResponseBody注解作用:
	//  该注解作用于将Controller的方法饭返回的对象
	//  通过适当的HttpMessageConverter 转换为指定格式后 
	//  写入到Response对象的body数据区,使用情况:返回的数据不是Html标签的页面,
	//  而是其他数据格式的数据时,(如 Json,xml,普通文本等)使用;
	//
	@ResponseBody
	public String doReqParam02(HttpServletRequest request) {
		return "obtain parameter's value is"+ request.getParameter("pageCurrent");
	}
	/**
	 *  最后:标准servlet API这种形式了解(实际有公司也在用)不作为重点
	 *  其实这种形式获取我们的参数 使用Servlet是不是也可以啊
	 *  那这种方式是不是写起来比较麻烦
	 * 
	 */
	
	//------第二种  === 直接量对象(重点)----------------直接量(八种对象类型+String+Date+数组)参数的获取-----------------//
	/**
	  * 
 	  * 
	 */
	//在这里可以直接用 这个变量去接收上面那种方式的参数值吗?
	//    假如可以按照(return "obtain parameter's value is"+ pageCurrent;)
	//    这么写 是不是比上面的方式简单了很多  肯定简单了 因为
	//    直接用一个变量来接收一个请求参数值
	// 在这里我们去用浏览器访问的时候 发现参数是可以正确传递过来的
	// 但前提是请求参数的名称必须要与方法的参数名称一致 假如不一致 是拿不到的这个值的
	// 想想: 这是为什么呢 或者说 它是怎么去实现的 是谁帮我处理的呢? 是谁把请求
	// 的那个参数注入到这个方法的参数
	// 
	// 此方法由谁调用:你现在就可以想是  DispatcherServlet 当然DispatcherServelt
	// 可能不直接调用它 它可能调用其他的对象 最终这个方法肯定是在DispatcherServlet中调用的吧
	// 此方法如何调用:反射  既然是反射调用这个方法 是不是实参传给形参
	// 那么此方法调用时参数如何注入:spring mvc 的底层 (基于参数名进行注入)
	// 有一个问题 我们地址栏传递过来的输入的内容都是字符串吧
	//  那在该例子中是谁把那个字符串直接转换成Integer类型的呢?这是不是我们思考的一个点
	//  假如我们使用Servlet 原生的API去取这个参数 是不是取到的是一个字符串
	//  那我想使用这个字符串 你是不是还需要把这个字符串转换成一个整数
	//  那么现在我们看到spirng mvc  有没有帮我们转换  当然了
	//  spring mvc  会把你请求的那个字符串 直接按照我们方法的参数名所对应的类型进行转换  然后注入给它
	//  假如我们在地址栏或者通过其他方式请求的时候没有传值 能访问到吗
	//  发现结果是null  那说明我这个参数是不是不给值也可以 但是在这个之前参数类型是(Integer)
	//  现在我要把它写成int呢  
	//           传递参数名称并传值:   会发生什么     结果:正确获取到值
	//          不传递参数名称不传值:会发生什么    结果:浏览器会抛出500错误    因为没有传递参数名称与参数值到控制器 所以获取到的值是null  而spring mvc 再将null
	// 赋值给基本类型的时候就会报错  所以 一般在开发中我们的属性的定义   经常是定义为Integer  也就是会定义为8中基本类型相对应的包装类 对象类型比较好
	// 因为这样是可以去接收传递过来的空值(null)
	// 接下来 我们进行如下操作  在地址栏里面我们不进行参数名称与参数值的传递 
	// 而是我们在方法的参数名称所对应的参数类型中去加上一个注解 @RequestParam 最后会是什么结果呢  
	//                         会发现报的是400-Required Integer parameter 'pageCurrent' is not present错误
	// 说说 在添加了注解的前提下 不给参数名称与参数值的情况下  会报错  那这个注解会是什么作用呢  注解修饰的这个变量是不是必须得给值
	// 不给值报什么错 那我给值还有400的错误吗   发现就没有了 也就是这个注解修饰的这个变量   必须得给值 没有给值就会报400错
	//接下来  我们对该注解进行修改并添加参数 如:(@RequestParam("page")表示的意思是:我们这个参数的值应该来自请求当中的哪个参数  没错 就是“page”这个参数)
	//这个时候如果继续请求并传递的参数名称是 pageCurrent 会报400错  如果换成 "page" 就可以正确的获取到值了 【参数名称名字比较长  或者 请求参数名称不一致 是不是可以采用这种方式】
	//那就是这个注解的一个作用
	// 在这这个注解中存在值的时候  它默认是 value = "page" [@RequestParam(value = "page")]  后面还有一个默认的  required  它的默认值是什么  true [@RequestParam(value = "page",required=true)]
	//不写默认就是true  假如你写false 就表示这个参数的值 可有可无  现象也就是去掉请求参数名称与值 就不会报错了 那如果要设置为true 必须要给值了  不给值就会报400错
	//400 一般表示客户端向服务端传递的参数不对    
	//注意在这个方法上加上参数  String  name [doReqParam02(String name,@RequestParam Integer pageCurrent)]  来看一下会不会取到值   没有传递值会不会报错
	
	public String doReqParam02(@RequestParam Integer pageCurrent) {
		return "obtain parameter's value is"+ pageCurrent;	
	}
	
	
	//现在来看一下方法参数是日期类型在接收请求参数的时候会是什么情况呢?
	@RequestMapping("doReqParam03")
	@ResponseBody
	public String doReqParam03(Date birthday) { //在这里的这个日期 我直接能拿一个对象来接收吗  可以 你页面上直接传一个字符串
		                                        //请求中可以直接将日期字符串 直接注入给此对象  怎么注入的 肯定是spring mvc 底层
		                                        // 要做一个日期的格式化
												//在这里传递参数的时候用“/”去分隔年月日的时候 服务器端是没有问题的   但是当用“-”去分隔的时候服务器端会报错
												//说明这种“-”在服务器端它不认识  那服务器端默认的日期格式是什么   就是“/”  spring mvc 定义规则呗
												//默认可以处理的日期格式:yyyy/MM/dd
		//不过spring mvc 也支持我们自己去设定格式 可以加如下注解[@DateTimeFormat(pattern="yyyy-MM-dd")在这里只写 "yyyy-MM-dd"的时候 发现会报错就说明不是将该值赋值给了value 而是其它描述作用的属性名称]
		//而在这里被设定之后 再去用其他格式的日期去传递参数的时候  也还是会报400错的  如“yyyy-MM-dd”  同样也是spring  mvc 来转换的日期格式
		return "obtain parameter's value is "+birthday;
		
	}
	
	//现在来看用数组/可变参数怎么来接收
	@RequestMapping("doReqParam04")
	@ResponseBody
	public String doReqParam04(Integer ...ids) { // . . . 写左写右都可以
		return "obtain parameter's value is "+ids; //在这里去输出的时候可以加上 Arrays.toString(ids)  不加显示的是一个对象
	}
	//客户端传参形式为ids=1,2,3,4  注意 : 客户端在传递的时候不要去给参数值添加 [ ]  即:[1,2,3,4] 这种形式  是错误的 不被spirng mvc 去识别
	//此时在浏览器客户端去请求的时候参数传递的时候是可以的 但是要用 “,” 来作为分隔符  将参数类型换成数组也是一样的  默认是用“,”来分隔的  当然写“/”是不行的
	//当然在这里也是spring mvc 进行转换的并注入给参数
	//优势 : 若使用标准的Servlet API 就需要先获取值 再拆分 在去作类型转换
	
	//当然在这里还有一些基本类型没有  如boolean类型等
	
	//接下里我们看  假如客户端请求参数是多个的话我们怎么做
	/**
	 * Java bean 对象(重点)
	 * 
	 * 当请求中多个参数时可以通过在方法中定义多个参数接收参数数据,也可以利用一个javabean对象接收多个参数
	 * 数据以简化多个参数变量的定义
	 * 
	 * 如果使用对象来接收数据的话 那我们页面上传的那个参数的值 需要和个对象里面的(不是属性)是set方法 必须要一致
	 * 也即:当使用JavaBean接收请求参数数据时,bean中需要有与参数名对应的set方法
	 * 
	 * 使用javabean(值对象,pojo-持久化对象)[javabean中的对象范围太广了 spring中的任何一个对象是不是都可以看成是一个bean呢]
	 * 在这里写的  值对象  就是我们所说的VO[value object]对象 pojo 这叫做什么对象  持久化对象
	 * 
	 * 注意: 请求参数名不能随便写  它需要和你的实体类里面的属性的get set方法一致吧
	 * 
	 * 这就是拿一个实体类 或者POJO对象  或者的任意的一个值对象封装值的 就是也提供了set  get方法
	 */
	  @RequestMapping("doReqParan05")
	  @ResponseBody
	  public String doReqParam05() {//doReqParam05(SysLog log)
		  //说明: 请求中的参数需要与pojo对象的set方法一致
		  //其实在底层也是spring mvc 帮我们去实现了 当然该写的逻辑与代码还要需要spring mvc 去实现的
		  // 只不过说它不是直接调用set方法 而是通过反射来调用set方法 去注入这个值而已
		  //当然在这里框架去调用 比我们直接调用性能肯定相对来说要逊色一些
		  
		  //因此在以一些秒杀系统中 直接使用框架的不多  就是Servlet 直接获取
		  //因为通过反射本身就是一个耗时的操作
		  return "";//"obtain parameter's value is"+log.toString();
	  }
	
	
	  //集合Map对象 -接收请求参数(了解)
	  /**
	      * 说明:通过map接收页面参数时,需要使用@RequestParam注解声明
	   */
	  @RequestMapping("doReqParam06")
	  @ResponseBody
	  public String doReqParam06(Map<String,Object> map) {
		  return "obtain parameter's value is"+map;
	  }
	  
	  //通过上述方式去接收浏览器客户端传递过来的参数 是不能直接去接收的  
	  //它是不认为这个map是可以存储参数的  那怎么办 在前面加一个注解@RequestMapping 看什么效果
	  //发现数据就有了  
	  //也就是如果需要用map 去接收浏览器客户端传递过来的参数需要去加一个注解去修饰
	  
	  //提示:假如方法参数是map 类型,而没有使用@RequestMapping注解进行修饰   此时的map不能再作为响应数据的封装
	  //此时的map 一般默认是用来封装响应数据的一个对象
	  
	
	  //rest url数据(重点)
	  /***获取rest风格url中的数据***/ 
	  @RequestMapping("doReqParam07/{id}")
	  @ResponseBody
	  public String doReqParam07(Integer id) {
		  return "obtain parameter's value is"+id;
	  }
	  
	  //通过上述方式之后 用浏览器去访问的时候  如:..../doReqParam07/1.do 去访问的时候发现是获取不到值的
	  //获取到的值是null
	  
	  //在这里可以加上一个注解   @PathVariable  [doReqParam07(@PathVariable Integer id)]  
	  //这个注解的含义就表示什么呢 我们参数中的这个值是来自我们请求中的一个url 叫path
	  //这个path是rest url风格中的url
	  //在这里如果将请求url 中地址的路径名称id与参数中变量的名称不一致发现会报错
	  //当然也可以在注解中去定义[@PathVariable("请求路径中对应的值")] 也可以  不过较少见
	  
	  @RequestMapping("doReqParam07/{id}/{name}")
	  @ResponseBody
	  public String doReqParam07_extend(@PathVariable Integer id,@PathVariable Integer name) {
		  return "obtain parameter's value is"+id+",name="+name;
	  }
	  
	  
	  //. . doReqParam07/{id}/{name}
	  //同时如果需要去传递多个参数 跟着写@PathVariable 就可以了  @PathVariable Integer id  @PathVariable String name
	
	  //在这里两个参数之间是有分隔符的 不然就不知道具体的将哪个值赋值给哪个参数
	  //在这里若参数之间有分隔符 而请求路径与第一个参数之间没有分隔符是可以访问的
	  //不过一般建议请求路径与参数之间添加上分隔符
	  
	  //对比:
	  //普通方式  http://ip:port/项目名称/doReqParam07.do?id=10&name=AAA
	  //rest url方式  http://ip:port/项目名称/doReqParam07/10/AAA.do
	  //优势:rest url 在网络中传输的数据少  速度会较快
	   

	
}

3.响应数据封装

package com.saint.ctms.ctrl;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@RequestMapping("/resp/")  //在这里两个注解先后顺序没有关系
@Controller
public class ResponseHandleController {
//======================响应数据的封装====================//

//将请求数据直接封装到Request对象
@RequestMapping("doRequestData01")
public String doRequestData01(HttpServletRequest request) {
	//在这里除了可以获取请求对象中的信息
	//还可以将数据封装到请求对象中
	request.setAttribute("data1","sys log message");  //直接将响应数据封装到了一个标准的Servlet API 中
	return "response";  //这种形式做的是一个转发  转发到一个什么地方  response页面
	//在返回的response页面中 //可以用类似(也就是EL表达式)${data1}方式去取名称为[data]的数据
	//在这里没有写 @ResponseBody的话   默认转发的是一个页面  是一个 view name  
	//然后底层会做这样的一个事情  返回的view 会通过视图解析器进行解析,获取具体的页面
	//谁来跳转的这个页面啊 -前端控制器 基于视图解析器返回的页面,进行请求转发
	//它是把我们拿到的数据转发到另外一个页面,否则你在那个页面拿不到数据  在这里执行的是请求转发 forward
	
	//那是重定向呢  重定向能拿到数据吗  来看一下
    }

//测试上面方法  重定向可否拿到数据
//结论: 发现肯定是取不到数据的
//请求转发:也称服务端做的跳转
//重定向:也称客户端做的跳转
@RequestMapping("doRespData02")
public String doRespData02(HttpServletRequest request) {
	request.setAttribute("data2", "request redirect message");
	//当需要重定向到某个url时,需要添加redirect前缀. 为什么要用redirect? 规则  spirng mvc 定的一个规则
	return "redirect:doRequestData01.do";
	//访问此方法时客户端向服务端底层发起了两次请求 先把这个地址返回给客户端 客户端又来访问这个地址吧  这里的前后的请求对象都被重新创建了  不是同一个
	//所以在实际项目  尽量不要使用重定向  为什么 客户端会重复向服务器端反复发请求
}

@RequestMapping("doRespData03")
public  ModelAndView doRespData03(ModelAndView mv) {//如果将mv作为参数    写在这里ModelAndView就不是我们自己来new 创建的   就是mvc 底层自己创建了一个mv对象  只是不用我们new 了
	 //ModelAndView mv = new ModelAndView();  可以自己new
	 //系统底层会将数据存储到reqeust作用域
	 mv.addObject("data01","model and view data");
	 //当系统返回mv时,经过视图解析获取view页面 ,并将请求准发到此页面
	 mv.setViewName("response");
	 
	 //在这里 ModelAndView中
	 //model=ModelMap  可通过源码查看
	 
	 return  mv;//此方法的返回值给了谁? 调用方  前端控制器  前端控制器通过反射来调用的这个方法    也就是在DispatcherServlet里面调用了我们这个后端控制器的方法    debug可看
	 //这里也用到了适配器模式 我们写的Controller 在spring  mvc 中还有一个叫法  叫handler  就是我们的Controller
	 //前端控制器会调用视图解析,对mv中的view进行解析  解析后会拿到这个页面后会
	 //前端控制器会将请求转发到视图解析器返回view页面
}

@RequestMapping("doRespData04")
public String doRespData04(Model m) { //在这里这个Model 可能会是谁 来看 Model  And  view  前面从源码看到 ModelAndView中的Model就是ModelMap 
	                                   //所以在这里Model 就是ModelMap 可以通过如下方法验证
	//验证Model 的类型  当然在这里Debug也是可以的
	System.out.println(m.getClass().getName());//BindingAwareModelMap   猜测它肯定是ModelMap的一个子类  
	                                            //查看源码发现继承关系是   BindingAwareModelMap-->ExtendedModelMap--> ModelMap
	
	//其实呢 这个Model可以做一个数据的绑定 m.addAttribute("","");
	
	//将数添加到请求作用域
	m.addAttribute("data1", "model message");
	
	return "response";
}

//那这【ModelAndView】 【Model】两种方式    该用哪个呢   这两种方式都可以解决我们的问题   
//那到底使用哪个呢 这个取决于你们的团队 每个团队都有自己的一个标准
//假如你数据是要在页面中使用EL表达式来获取   在服务器端对数据的封装最常用的就这两种方式

//不使用El表达式获取呢  后面会讲  还有其他的

//还有一种写法  老师说不太常用的    尽量不要用这种形式  那sprig中为什么要提供一个Model啊   其实这个Model是不是指向的一个map  它底层会适配选择一个map 不用你自己写map去了
//假如你使用map  推荐上面Model这种方式
//将响应数据封装到Map中 (我建议假如使用map对数据进行封装,可直接使用model对象
//在这里 不加@RequestParam  一般是可以用来封装响应数据
//加上之后  就是接收请求参数
@RequestMapping("doMap01")
public String doMap01(Map<String,Object> map) {
	map.put("data", "map . . .");
	return "response";
}   
//==============================响应数据的转换=========JSON=============================//
//JSON:  就是一种数据格式     符合这种格式的字符串 就叫做JSON格式的字符串"{id:10,name:AAA,....}"
//JSON对象   一般指的是JSON格式的JavaScript对象  就是把最外层字符串去掉

@RequestMapping("doRespJson01")
@ResponseBody //在这里如果不加该注解  会报404错误   发现浏览器客户端不是找的map.jsp而在找的是 doRespJson01.jsp
public Map<String,Object> doRespJson01(){
	Map<String,Object> map  = new HashMap<>();
	map.put("id", 10);
	map.put("name","涛哥哥");
	return map;//在这里发现以这种形式去返回同样会报500错   因为你添加了@ResponseBody注解  会把map去尝试转换为字符串  
	           //但是会发现没有把map转换为字符串的转换器  所以在这里会报 
    		   //no converter found for return value of type:class java.util.HashMap
			   //spring mvc 不支持将这个直接将对象转换成JSON格式的字符串     需要借助第三方的库  可以添加 jackson  这个时候我们什么都在没有做
               //再去运行项目发现数据响应正确显示了
	           //Spring mvc 系统底层可以调用
			   //第三方的API将map对象转换为JSON格式的字符串
			   //例如:jackson (spring [mvc] 默认支持   只需要添加依赖)    提供了map--->JSON的转换器  前提是有 @ResponseBody 注解
			   //阿里:fastjson (spring [mvc] 默认不支持)想用就需要添加完依赖再配置就行了
	
			   //jackson采用的什么默认转换器呢  在这里我将spring 配置文件中  <mvn ...> 去掉会发现  项目重新访问的时候报406错误 
               //不会再将map转换为   JSON字符串输出了
			   //这里的406是什么意思呢  这是服务端向客户端返回的数据被拒绝接收了
    }
    
   //406: 也就是服务器没办法将返回的值转换成特定格式的字符串返回到客户端
	//启用spring mvc 默认配置(底层支持jackson)
	//<mvc:annotation-driven/>
	
	
	//<mvc:annotation-driven/>
	//其实就是启用 相关注解以及相关Bean对象的默认配置(例如 底层就会支持jackson)
	//假如不想用一些默认的配置 那么就在这里需要做一些简单的
	//改动去设置
	
	//说明:对于此返回转换为json格式字符串.需要
	//在配置文件中添加<mvc:annotation-driven/>配置
	//假如没有这个配置系统底层可能会出现406的问题
	
	@RequestMapping("doRespJson02")
	@ResponseBody
	public Map<String,Object> doRespJson02(){
		List<Map<String,Object>> list = new ArrayList<>();
		Map<String,Object> map = new HashMap<>();
		map.put("id", 10);
		map.put("name", "涛哥哥");
		list.add(map);
		map = new HashMap<>();
		map.put("id", 100);
		map.put("name", "陈枢枢");
		list.add(map);
		return map;
	}
	
	public String doRespJson03() {
		return "{\"id\":100\",\"name\"=\"AAA\"}";
		//在这里我们可以自子去拼接 但是这样的话 是比较麻烦的
	}
	
	//@RequestMapping("doRespJson04")
	//@ResponseBody
	//public SysLog doRespJson04() {
		//SysLog  log = new SysLog();
		//log.setId(100);
		//log.setUsername("admin");
		//log.setMethod("login");
		//log.setDate(new Date());
		//return log;
	    //返回的是一个对象  将此对象转换为JSON字符串的时候
		//会调用对象的get方法获取值
		//所以说你这个对象要是没有提供get方法是不是拿到的就是空(NULL)啊
		//可能就没有那个数据	
	    
	   //通过浏览器在客户端去访问的时候
	   //发现响应对象显示的日期类型是long(如:153265874522142)类型
	   //那为什么要转换成long类型呢  它为什么不转成一个日期格式呢
	   //这个数据一般有它一个设计的思想
	   //这个数据是不是可能在不同的客户端进行呈现
	   //pc  移动端   手机  手表 电视  中国人 外国人 英文系统 中文系统
	   //如果将格式为中文日期 其他例如外国人就看不懂
	   //所以在服务端去固定一个格式  好吗  不好
	   //干脆所以服务端就返回长整型  那你需要什么的格式 你自己来搞定 去转
	   //而这些数据是在get方法中取到的 那完全可以在get方法中去转换成你需要的格式
	   //那你get方法返回的是一个Date那你把它可以改成一个String 可以吧  可以
	   
	
	   //在这里你服务器端返回的是一个对象 spring  自动会把你
	   //这个对象转换为一个JSON字符串
	   //那请问这个JSON字符串是怎么返回到客户端的
	   //是不是一个response对象
	   //response。getWriter().write()
	   //从响应对象中去获取一个流对象  然后将字符串
	   //写入并返回到客户端  但是这个过程我们自己写了吗
	   // 谁帮我们做的呢  是spring  mvc 
	   // 那spring  mvc 为什么要做这个工作呢
	   //因为这段代码的重用性太大了 几乎我们向客户端输出
	   //数据输出一个串我们都要这样来
	//假如我们没有使用spring  mvc 我怎么办 
	//那我们就自己把这个对象转换成一个JSON格式的字符串可以吧
	//  
	
	
	//@RequestMapping("doRespJson05")
		//@ResponseBody
		//public String doRespJson05() {  直接返回字符串
			//SysLog  log = new SysLog();
			//log.setId(100);
			//log.setUsername("admin");
			//log.setMethod("login");
			//log.setDate(new Date());
	        //ObjectMapper om = new ObjectMapper(); 借助第三方自己来转换  此处API 来自jsckson
			//String s = om.writeValueAsString(log);
			//在这里发现浏览器客户端访问的时候 中文是显示乱码
			//在哪里会是乱码呢  可以在返回前加上这样一句话
			//System.out.println("s="+s); 发现这里并不是乱码
			//那假如转换完不是乱码
	        //那就说明这个数据是从服务器端写到客户端的时候变成乱码的
			//就是response.getWriter().write()... 也就是在估计在该操作的时候变成乱码的
	//这里我们对于这个写入到客户端JSON数据的操作 我们可以去掉spring 的 <mvn:. . .>的默认配置
	//通过我们自己写的API将数据转换成JSON串 可以吗 可以
	//当默认方式不支持其他的第三方的API  我们就可以自己转
	//那在这里服务端是不是将数据写入到客户端   服务端相当于生产者
	//客户端相当于 消费者  所以在@RequestMapping("doRespJson05")注解中可以进行如下配置
	//@RequestMapping(value="doRespJson05",produces="application/json;charset=utf-8")  这个时候发现客户端不会再是乱码了 正确显示中文了
	//假如将这里的application/json格式写错了  浏览器会下载文件将内容放在其中  但是怎么避免写错了呢
	//@RequestMapping(value="doRespJson05",produces="MediaType.(这里去点出来要设置的类型 当然导入的也是spring包);[charset=utf-8"]前面点出     来的常量可以代替这段字符集编码)
	
	//练习  将fastjson 设置问spring的默认转换器
	
	//return s;
 //}
	
	
	
	public static void main(String[] args) {
		System.out.println();
	}
}

4.配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- 组件扫描 -->
	<!--配置spring中Bean对象的扫描(包括后端控制器)
	component-scan 元素用于扫描指定的包以及子包中的类
	并且会将使用了@Controller,@Service等类似注解
	修饰的类交给Spring IOC容器管理。
	  -->
	<context:component-scan base-package="controller"/>
	  <!--启用spirg MVC默认配置
	          就是需要在mvc的一些默认配置我们需要去初始化 
	            如:参数的类型转换  响应数据的一些转换  它底层内置的一些转换器
	   -->
	  <mvc:annotation-driven/>
	  
	  <!-- 拼接路径 -->
	  <!--  配置spring mvc视图解析器(负责视图解析操作)  -->
	  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	     <!--前缀  -->
	     <property name="prefix" value="/WEB-INF/pages/"/>
	     <!--后缀-->
	     <property name="suffix" value=".jsp"/>
	  </bean>
	
	
</beans>
上一篇:springMVC(三)-处理数据模型及@requestModelAttribute


下一篇:SpringMVC基本应用