/**
 * 此对象应用于处理DispatcherServlet(SpringMVC中的核心处理器)交给它的请求
 */
@Controller//此注解描述的对象为Controller请求的处理器对象,我们通常称之为handler
public class TemplateController {
    /**
     * @RequestMapping 注解描述方法时用于定义请求url到handler中方法的映射
     * @return view 的名字
     * 请求地址:http://localhost/doTemplateUI
     * 请求的的简易处理过程
     * 1)基于域名获取ip地址(例如:127.0.0.1)
     * 2)基于ip地址找到网络中计算机(ip地址是网络中计算机的唯一标识)
     * 3)基于端口找到tomcat服务(port是计算机中应用的唯一标识)
     * 4)tomcat服务会基于thread并借助io读取网络http协议中请求数据
     * 5)tomcat内部会创建请求(request)和响应(response)对象,用于封装请求和响应信息
     * 6)tomcat会调用Filter对象对request数据进行过滤
     * 7)Filter对request过滤以后,会将请求交给DispatcherServlet进行处理?
     * 8)DispatcherServlet读取请求中的url,并基于url从requestMapping中找到对应的handler以及方法
     * 9)DispatcherServlet基于反射技术调用handler方法
     * 10)DispatcherServlet会将handler方法返回的view等相关信息进行封装,然后交给视图解析器进行解析
     * 11)ViewResolver视图解析器对为view name添加前缀,后缀,并将model中数据填充到view中
     * 12)DispatcherServlet 将视图解析器解析的结果封装到response对象,并将其响应到客户端。
     * 说明:
     * 1)此方法是DispatcherServlet基于反射技术进行调用?
     * 2)反射技术的最大优势?不能预知未来,但可以驾驭未来。
     */
     @RequestMapping("/doTemplateUI")
     public String doTemplateUI(){
           return "default";//view name
           //思考?
           //1)这里的返回值会交给谁?当然是方法调用者(DispatcherServlet)
           //2)dispacherServlet会将方法的返回值封装到ModelAndView对象中
           //3)将ModelAndView对象交给视图解析器(ViewResolver)进行解析
           //4)视图解析器对为view name添加前缀,后缀,并将model中数据填充到view中
           //4.1)默认的前缀为/templates/,默认的后缀为.html
     }

}

=================================================================================================

/**
 * 在此对象中演示请求中参数的处理过程
 */
@RestController
public class ParamObjectController {
       //访问:http://localhost/doParam01?id=10
       @RequestMapping("/doParam01")
       public String doMethodParam(HttpServletRequest request){
            String idStr=request.getParameter("id");
            //假如我们后面业务需要的是一个整数,此时还需要进行类型转换
            Integer id=Integer.parseInt(idStr);
            //后续可以基于整数id值执行后面的业务了,例如删除,查找...
            return "request params id's value is "+id;
       }

       //访问:http://localhost/doParam02?id=20
      //当使用方法参数直接获取请求数据时,方法参数名要与请求参数名相同
      @GetMapping("/doParam02")
      public String doMethodParam(Integer id){//框架的力量
        return "request params id's value is "+id;
      }
    //访问:http://localhost/doParam03?ids=1,2,3,4
     @RequestMapping("/doParam03")
     public String doMethodParam(Integer[] ids){//框架的力量
           //....
        return "request params ids's value is "+ Arrays.toString(ids);
     }

    //访问:http://localhost/doParam04?startTime=2020/12/31
    //假如方法要接收日期格式对象可以通过@DateTimeFormat注解指定可接收的日期格式
    //默认格式为yyyy/MM/dd
    @RequestMapping("/doParam04")
    public String doMethodParam(
            @DateTimeFormat(pattern = "yyyy/MM/dd") Date startTime){//框架的力量
        //....
        return "request params startTime's value is "+ startTime;
    }
    //访问:http://localhost/doParam05?name=tony&page=2
    //假如在方法参数中需要指定某个参数的值必须在请求参数中有传递
    //@RequestParam注解用于描述方法参数,用于定义参数规则
    //1)方法参数变量的值,来自哪个请求参数,例如@RequestParam("username")
    //2)方法参数变量是否要必须传值 例如@RequestParam(required = true)
    //@RequestMapping(value="/doParam05",method = RequestMethod.GET)
    @GetMapping("/doParam05")
    public String doMethodParam(
            @RequestParam(value="name",required = false) String name,
                      @RequestParam(required = true) Integer page){
        return "request params 's value is "+ name+":"+page;
    }
    //====================POJO对象方式=============================
    //http://localhost/doParam06?name=tony
    //当使用pojo对象封装请求参数信息时,请求中的参数名应与方法参数pojo对象
    //中的set相关方法相匹配
    @GetMapping("/doParam06")
    public String doMethodParam(RequestParameter param){
        return "request params 's value is "+param.toString();
    }

    //@GetMapping("/doParam07")//http://localhost/doParam07?name=tony&ids=1,2
    //post请求可以借助postman工具进行访问
    @PostMapping("/doParam07")//http://localhost/doParam07
    public String doMethodParam(RequestParameter param,Integer... ids){
        return "request params 's value is "+param.toString()+",ids="+Arrays.toString(ids);
    }


    //====================Map对象方式=======================
    //http://localhost/doParam08&code=1&message=ok 假如以这样方式直接在浏览器地址栏访问会有405异常
    //post请求可以借助postman工具进行访问
    //使用map作为方法参数封装请求数据,默认是不可以,因为默认底层会认为这个map是用于封装响应数据的.
    //可以借助@RequestParam对map进行描述,来接收请求参数
    @PostMapping("/doParam08")
    public String doMethodParam(@RequestParam Map<String,Object> map){
        return "request params 's value is "+map.toString();
    }

    /**
     * @RequestBody注解描述方法参数时,客户端
     * 可以以post方式提交json格式的数据,
     * 说明:@RequestBody注解描述的方法参数不能封装Get请求数据
     * @param map
     * @return
     */
    @PostMapping("/doParam09")
    public String doMethodJsonParam(@RequestBody Map<String,Object> map){
        return "request params 's value is "+map.toString();
    }

    @PostMapping("/doParam10")//http://localhost/doParam10
    public String doMethodJsonParam(@RequestBody RequestParameter param){
        return "request params 's value is "+param.toString();
    }
    //=========================rest 风格url参数获取===================
    //rest风格:软件架构编码风格(跨平台)
    //rest风格url的定义:/path/{var1}/{var2},这里的{}括起来的为变量
    //@PathVariable 注解描述方法参数变量时,表示这个参数的值来自url中{}表达式给定值
    //例如:
    @GetMapping("/doParam10/{id}/{name}")
    public String doMethodRestUrlParam(
            @PathVariable  Integer id,@PathVariable  String name){
        return "request params 's value is id=" + id+",name="+name;
    }

}

=================================================================================================

//@Controller
//@ResponseBody
@RestController //==@Controller+@ResponseBody
public class JsonController {
    /**
     * 假如@ResponseBody注解描述的方法,它的返回值是一个pojo对象,底层在将其转换为
     * json格式字符串时,会默认调用pojo对象的get方法,会使用get方法名中get单词后面的名字
     * 作为key(首字母小写),get方法的返回值作为value,拼接json格式字符串.
     * @return
     */
    @RequestMapping("/doConvertResponseToJson")
    //@ResponseBody
    public ResponseResult doConvertResponseToJson(){
        ResponseResult result=new ResponseResult();
        result.setCode(200);
        result.setMessage("OK");
        return result;
    }

    /**
     * http://localhost/doConvertMapToJson
     * 当使用@ResponseBody注解描述控制层的handler方法时,假如此方法的返回值
     * 为map或pojo这样对象,系统底层会将这样的转换转换为json格式字符串,然后响应到客户端.
     * 思考?
     * 1)在当前应用中这个json格式的字符串会写到http协议的哪一部分中,然后响应到客户端?(响应体)
     * 2)谁将这个map转换为了json格式字符串呢?springboot工程默认使用的是jackson (这组依赖
     * 是我们项目中添加spring web依赖时自动添加的)
     */
      @RequestMapping("/doConvertMapToJson")
      //@ResponseBody
      public Map<String,Object> doConvertMapToJson(){
          Map<String,Object> map=new HashMap<>();
          map.put("state", 1);
          map.put("message", "ok");
          return map;
      }

      @RequestMapping("/doPrintJsonToClient01")
      //@ResponseBody
      public String doPrintJsonToClient01() throws JsonProcessingException {
        Map<String,Object> map=new HashMap<>();
        map.put("state", 1);
        map.put("message", "ok");
        //将map手动转换为json字符串
        ObjectMapper objectMapper=new ObjectMapper();
        String jsonStr=objectMapper.writeValueAsString(map);
        System.out.println("jsonStr="+jsonStr);
        //将这个json字符串响应到客户端
        return jsonStr;//当方法使用了 @ResponseBody注解描述,则方法的返回值就不再是view了
      }
    @RequestMapping("/doPrintJsonToClient02")
    //@ResponseBody
    public void doPrintJsonToClient02(HttpServletResponse response) throws IOException {
          //看过去(最早都是我们自己拼接字符串为json格式)
          //String jsonStr="{\"state\":1,\"message\":\"成功\"}";
        //进阶过程
        Map<String,Object> map=new HashMap<>();
        map.put("state", 1);
        map.put("message", "成功ssssssssssssss");
        //将map手动转换为json字符串
        ObjectMapper objectMapper=new ObjectMapper();
        String jsonStr=objectMapper.writeValueAsString(map);
        System.out.println("jsonStr="+jsonStr);
        //将这个json字符串响应到客户端
        response.setCharacterEncoding("utf-8");//设置响应数据的编码
        response.setContentType("text/json;charset=utf-8");//告诉客户端响应数据的类型以及编码
        PrintWriter out=response.getWriter();
        out.println(jsonStr);
        out.flush();
    }



}