spring入门笔记

public class spring {


        //    HTTP是一套应用层协议  请求响应模式
        //    web资源以服务的形式体现
        //
        //    请求 :有客户端发起 服务端接收
        //    响应:有服务端发起 客户端接收
        //
        //    Http格式:
        // 请求
        //    1.请求行 (请求方法 (POST GET ) 资源URL    版本)
        //    2.请求头 (KEY VALUE格式 每个占一行 ) 直到遇到空行截止
        // 3.POST才有,请求体(本次要提交的数据)
        //
        // 响应
        // 1.响应行 (响应版本信息  响应结果 (状态码+状态描述) )
        // 2.响应头:  (KEY VALUE格式 每个占一行 ) 直到遇到空行截止
        // 3.响应体(如果有的话):资源内容
        //
        // 继承 HttpServer 写服务器
        // text/html:是一种html格式的文本
        //
        // web资源:
        // 1.内容格式 2.生成方式(动态 静态)  url 内容长度


        //
        // url:协议(http(s)://) 服务器地址(ip) 服务器端口号  带层次的文件路径 ?参数
        // url网络中的所有文件都可以使用url命名
        //
        // 端口(TCP端口) 本机:127.0.0.1:8080 当端口是标准端口是可以省略
        //
        // 对于静态资源,有个目录,称为资源的根(如static) ,这个目录下的所有资源被视为静态资源
        //   写的时候一般很少些全路径
        // 1.写url是一般省略协议号
        // 2.可以省略除路径之后的全部部分 (访问的是本机 )
        // 3.路径分为相对路径和绝对路径(绝对路径从根开始,相对路径从当前目录开始 可以想象a标签的href html的相互引入等)
        // 4.  ./相当于原地顿一下
        // 静态资源的默认路径是static(我试过 仅限本项目) 要想访问HTML.html(在static的第一级目录下) 直接/HTML.html
        // 动态资源:@Controller 标注的类,简单认为就是放置动态资源
        //         @GetMapping 标注的方法,是一个动态资源,注解中写明动态资源的资源路径是什么 GetMapping代表这个资源支持GET方法
        //   请求参数:?后面的  键值对 用&区分  ?key=value&keyy=valuee
        //
        //   URL编码:路径中不能出现中文 中文需要经过字符编码
        //   1.指定字符集(默认UTF8)      以xx编码要以xx解码
        //   url编码 将汉字->16进制        url解码 16进制->汉字
        //
        //   如何编写一个动态资源
        //
        //   SSM Spring(Springboot)SpringMVC Mybatis
        //   Spring (Springboot) 提供了LOC功能
        //   loc:控制反转  DI:依赖注入 loc是一种理念 di是这种思想的具体实现
        //   SringMVC 提供web开发能力
        //   Mybatis:提供了比直接使用JDBC更方便的数据库操作能力
        //
        //   进入ssm开发阶段 使用大量注解进行标注
        //   所谓注解 可以为方法 类 变量添加额外的信息 @
        //   @Controller :简单认为就是放置动态资源
        //
        //   下面三个可以修饰书类和方法 我们先关注方法
        //   @RequestMapping(“资源路径”):是一个动态资源,注解中写明动态资源的资源路径是什么 代表这个资源支持HTTP所有方法
        //   @GetMapping(“资源路径”):是一个动态资源,注解中写明动态资源的资源路径是什么 代表这个资源支持GET方法
        //   @PostMapping(“资源路径”):是一个动态资源,注解中写明动态资源的资源路径是什么 代表这个资源支持POST方法
        //
        //
        //  @ResponseBody  //响应体  这个注解修饰的方法表示该方法完整的返回了整个响应体的内容
        //  punlic String f(){
        //     //返回的格式默认是HTML格式       //背后有Spring处理
        //     return <h1>2<h2>
        //  }
        //  ************************************************************************************************************
        //  调用资源操作( @Controller)  vrey 重要****    由Spring处理
        //  1.利用反射机制 得到类的实例化
        //  2.扫描该类的所有方法by 反射  找到被 @RequestMapping()修饰的所有方法
        //  读取资源文件 最终得到Map  Map<String,方法> key:资源  value:对应的某个方法
        //  3.当有请求来时,一定可以找到对应的资源路径 根据map找到对应的方法
        //  4.调用该方法 第二步实例出来的对象
        // ****************************************************************************************************************
        // HTTP请求:
        // 请求方法:表达本次请求我们想要对这个资源做出神魔样的动作
        // 最常见的:获取get   提交post
        // 还有其他的
        // 在浏览器输入URl一定是GET
        // POST <form>表单可以 Method=post
        //      javascript 发起HTTP请求(ajax)
        // 当输入的不符合url格式,浏览器会进行搜索(当做一个搜素词,而不是路径)
        // html标签也可以发http请求;<a>  <script>  <link>
        // 通过ajax发起post:(使用比较多)
        // js代码:
        // 实例化一个XMLHttpRequest 对象,简称XHR
        // var xhr=new XMLHttpRequest()
        // 调用对象的open()方法 设置请求的 1)方法 2)路径
        // xhr.open('get','/demo') // get   // (xhr.open('post','/demo')  post)
        // 设置回调函数 当/demo 资源的响应返回时,应该干什莫
        // //事件绑定机制
        // xhr.οnlοad=function(){  //响应回来时
        // console.log(xhr.status)//响应的状态
        // }
        //
        // xhr.send()  发送请求
        //
        // GET 类似于对web资源进行 SELECT
        // POST 类似于对web资源进行  INSERT
        // PUT 类似于对web资源进行 UPDATE
        // DEKETE 类似于对web资源进行 DELETE
        //  假设  访问某资源(/resource)得到的响应时R1
        //  幂等性:无论何时,随时访问/resource得到的都是R1,不会改变  假设环境是没有变得
        //  反之,就不具备幂等性
        //  副作用:会不会当值资源变化
        //   GET具备幂等性,且无副作用
        //   POST不具备幂等性,有副作用
        //   PUT具备幂等性,有副作用  假设UPdate的结果返回表的最新数据
        //   DEKETE 不具备幂等性,有副作用
        //
        //   GET应该是幂等性,且无副作用,should 不是 must 所以在现实中因为否写原因违反规则是可以使用的
        //    幂等性+无副作用的HTTP请求是可以被缓存的。
        //    缓存:由于某些性能上的考虑,并不是每次请求都要服务器参与,而是将结果暂时性的保留一段时间 供下次使用
        //   GET请求不允许有请求体  Post允许有     理解select于insert
        //
        //   那我自己写一个http客户端,如果携带了请求体,会怎摸样?
        //   就要看具体实现: 对方可以胡略你的请求体 也可以不乎略
        //
        //   理论和实践: 你叫我做事,我可以听,也可以不听
        //
        //  现象:GET把数据携带URL中 POST放在请求体中
        //  例如form中对于相同的数据<input name=“”> get name会放在url中 post会放在请求体中     都是相同的数据,存放的位置不同
        // @RequestMapping(“资源路径”)和@ResponseBody可以同时作用于一个方法上 因为ResponseBody无路径 可以理解我要你的返回值和你做业务逻辑不冲突
        //    url长度一般不易太长(没要求) ,而请求体无限制
        //    GET在query string 中无论携带什么数据,总体上还是key=value 但post则更灵活(非form表单)
        //
        //   var xhr=new XMLHttpRequest()
        // xhr.open('post','/demo')
        //
        // xhr.οnlοad=function(){
        //
        // }
        //
        // xhr.setRequestHeader('Content-Type','text/peixinchen') //请求头中规定请求体的格式
        // xhr.send("随便写,按照Content-Type的格式就行")  发送请求
        //
        // 由于浏览器发送非GET请求不方便,有专门的工具发送HTTp请求 Apifox
        //
        // HTTP请求---资源路径
        // 填写完整的URL 或者是绝对路径,(不会出现相对路径) 但是可以有 查询字符串(也就是参数)和文档片段
        //
        // 请求头 key--value格式  key和value中不能有中文
        // Name有标准的,不提没大家都知道  也有自定义的:只有自己知道,建议用自定义Name用X-开头 X-courseId:xxx
        // 标准的Header中有些请求是专用的,有些是通用的
        // 专用:host    通用:Content-Type
        //
        // 文本类型:
        // multipart/form-data                    主要用于form表单+上传文件 (后面会有)
        // application/x-www-form-urlencodeded     form默认的格式 key-value格式
        // application/json                        马上要讲的json格式
        // application/xml                          (不讲)  XML(pom.xml)
        // text/plain                               无格式文本
        //
        // Http响应
        // 响应行 =响应版本+状态码+状态描述(可省略)
        // 响应头
        // 空行
        // 响应体
        //
        // Http响应--版本 Http/1.1
        //
        // Http响应--状态
        // 用来表达本次请求-响应的结果
        // 1.成功
        // 2xx
        // 200 成功
        // 2.失败
        // 客户端 4xx  400 缺少必要的参数  404 请求的路径对应的资源不存在 405 请求的方法对应的资源不支持 (getMapping 请求PostMapping)
        // 服务器 5xx 500 代码出现异常
        //
        // 3.其他情况
        // 流程继续 1xx c处于一定的流程中,还在继续
        // 重定向   3xx  301 永久重定向
        //
        // 在开发者工具勾选 保留日志 和 停用缓存
        //
        // 重定向:
        // 我去书店买                        石头记                第一次请求
        // 老板说石头记改名了叫红楼梦                               第一次响应 【重定向】
        // 我向老板买                        红楼梦                 第二次请求
        // 我拿到了红楼梦                                           第二次响应                 也可以站外重定向 :老板说去XX店买
        //
        // @GetMapping("/redirect-demo")
        // public String redirectDemo(){
        // //这里是死规定 redirect:+资源url组成
        // return “redirect:/”;  //   ‘/’是首页  站内重定向 站外是不再本项目中
        // 或 return “redirect:www.baidu.com”   站外重定向
        // }
        //
        // “/method-form.html” 绝对路径
        // “method-form.html”  相对路径 相对于 /redirect-demo 所在的目录是 /
        //
        // 重定向还可以继续分类:永久重定向(301)和临时重定向
        // 临时重定向可细分  重定向一定是两种请求响应
        // POST 请求 /r1
        // 重定向到/r2
        // 问 /r2使用的post or get?
        // 之前没做处理     都可以 302
        // http 1.1 做了明确规定
        // 1.请求方法保留第一次的请求方法 POST+POST  307
        // 2.   请求方法退化为GET                    POST+GET   303
        //
        // 网络 保留日志 停用缓存
        // 重定向和Http响应的关系
        // 1.状态码:301 302 303 307
        // 2.响应头中有Location 他的value写明让浏览器去再次请求的url
        // 3.一般重定向响应是没有响应体,即使写了也不保证客户端会去读取使用
        //
        // ajax的请求 后续的控制全是代码完成 即使是重定向浏览器也不会自动跳转(该有的请求都有) 也不支持站外重定向
        // 但form表单 重定向浏览器会自动跳转
        //
        // location.assign():也会页面跳转,
        // 请求转发:forward
        // 我 买石头记
        //           老板找了本红楼梦包装成石头记卖给我
        //  我买到了石头记
        //  只有一次请求响应
        //  return “forward:/method-form.html”
        //
        //  SSM中静态资源放在 recoures/static/下
        // 动态资源放在src/main/java 代码下 @Controller +@requestMapping
        //
        //  content-type: MIME-type 标准
        //  如果是文本类型,可以通过如下格式指定字符编码
        //  text/plain;charset=utf-8
        //  解释:大类型 text  表示文本类型
        //        小类型 plain(无格式) 表示没有任何具备格式的文本类型--纯文本
        //        charset=utf-8  文本的字符集采用utf-8
        //
        // 最常见 类型
        // 1.大文本类型
        // text/plain   纯文本
        // text/html            HTML结构的文本
        // text/css
        // text/javascript
        //
        // 2.应用类型
        // application/javascript    javaScript结构的应用
        // application/json         javascript Obiect Notation 比较便捷的携带 人类可识别的 结构化数据的 主要用于前后端分离
        // application/x-www-form-urlencodeded     form默认的格式 key-value格式
        //
        //  3.多媒体
        //  image/jpeg  png
        //
        //  4. form表单+上传文件
        // multipart/form-data      大类型:多部分--正文中的内容是由多个部分组成的 小类型 form-data 每个部分是form提交数据
        // 使用时修改form类型  <form enctype="multipart/form-data"> 主要和<input  type="file name=..">进行配合
        //
        // 1.JSON格式  (以字符串来体现)
        // js对象格式:大括号
        // {      name:value,name1:vale1                   }
        // 其中name必须是字符串类型  value可以是任意类型
        // JSON下,做了一些约束({}可以换做[] 代表数组)
        // 1.name必须是双引号包裹(js可以省略引号,也可以使用单引号)
        // 2.value类似不能是函数类型  只剩数据(去除了动作) 可以为null 但不会有undefined(默认为null)
        // 3.jsvascript和后端都很容易解析哦
        //
        //                       json序列化:JSON.stringify(..)  obj/array-->string
        // js下的数据(对象 数组)----------->JSON格式化的字符串
        //                   <------------ JSON反序列化 JSON.parse(..) string-->obj/array
        //  后端:java 和js不同 没有官方提供的JSON提供的序列化 反序列化工具 借助第三方代码完成 目前使用最多
        //  1.jackson SSM默认使用jackson(咱们不用处理 springmvc 内部处理)
        //  2.gson
        //  3.fastjson 阿里的
        //
        // java中序列化 反序列话
        // Person p=new Person();
        // p.name="ysg";
        // p.age="103;
        // p.teacher=true;
        // ObjectMapper om= new ObjectMapper();
        // String s=om.writeValueAsString(p);
        //     System.out.println(s);
        //
        //     map 在数据格式方面和对象是等价的
        //      Map<String,Object> map=new HashMap<>();
        //       map.put("名字","走起来");
        //       map.put("age",103);
        //       map.put("isTeacher",true);
        //       map.put("弟子","走起来sd");
        //       ObjectMapper om= new ObjectMapper();
        //         String s=om.writeValueAsString(map);
        //         System.out.println(s);
        //
        //         反序列化 :
        //         String s="{\"name\":\"tony\",\"age\":18}";   /  /转义“
        //             String s="{\"name\":\"tony\",\"age\":18}";
        //       ObjectMapper om=new ObjectMapper();
        //       Person p=om.readValue(s,Person.class);
        //       //map
        //         Map map=om.readValue(s,Map.class);
        //
        //         1.动态资源使用JSON:
        //         1.得必须被@RequestMapping 修饰 代表是动态资源
        //         2.方法应该被@ResponBody 注解修饰 表示返回的内容填充到响应体中
        //         3.方法返回值类型必须是 某个类 Map list 等集合
        //         @GetMaping("/json-of-json")
        //         public Person json{  //map也行 list也行
        //         Person p=new Person();
        //         p.name="sss";
        //         p.age=2
        //          return p;            //ssm内部会将对象序列化成JSON格式
        //          }
        //       2.从请求体中读取JSON格式得字符串,并直接在动态资源中使用 【相对用的较多 前后端分离】
        //       注: @ResponseBody+String 返回值类型就不是 application/json ,而是text/html格式
        //       形参被@RequestBody 修饰 表示从请求体中得到内容
        //       形参的类型是: Map 对象 list
        //       @PsotMapping("/read-person")
        //       @ResponseBody
        //       public String readPreson(@RequestBody Person person){
        //       return "OK";
        //       }
        //
        //       前后端数据交流用json
        //
        //       结论:前端完全把后端当作一个简单的存取数据的子系统,通过Ajax http +json 进行通信 根据数据修改DOM树
        //       Dom 添加孩子节点有两种方式
        //       1.element.innerHTML+=HTML 字符串
        //       2.child =document.createElement(..)
        //       element.appendChild(child)
        //
        //       var tbody document。query Selector(‘tbody’);
        //       for(var m of ml){
        //       //m 是元素
        //       var html=‘<tr><td>${m.who}</td><td>${m.whom}</td><td>${m.what}</td></tr>'    '为模板字符串
        //       tbody.iinnerHTML+=html  //添加一个孩子
        //       }
        //
        //       前端向后端提交数据有两种方式
        //       1.采用form
        //       form的后续处理,建议使用 重定向 这样浏览器自动就会重定向到指定资源上
        //       2.ajax+请求体;JSON的形式
        //       ajax的后续处理,建议返回还是json,方便js根据情况继续处理
        //
        //
        //       要重定向的动态资源不要写@ResponBody
        //
        //
        //
        //
        //
        //
        //
        //
        //
        //       购买云服务器   腾讯云 阿里云  百度云 华为云
        //       一年:40-120  1核1 2g 就行
        //       安装OS的时候 选择CentOS 8.X都行  重装系统很容易
        //
        //
        //
        //
        //
        //
        //       <input type="file" name="ccc">  //一个按钮,可以点击选择一个文件  需要搭配 form的enctype="multipart/form-data"使用
        //      这时请求体是由多部份(multipart)组成,每个部分之间靠边界(boundary)来分割
        //      boundary样子:-------------------------------------156443231255445641233212566123  //数字是随机的
        //
        //      文件上传后进行文件的保存 利用输出流复制文件 一个一个字节读 或直接交给SpringMVC
        //      @Controller
        //      public class UploadController{
        //      @PostMapping("/upload.do")
        //      @ResponseBody
        //      public String upload(MultipartFile ccc) throws Exception {
        //      ccc.transferTo(new File("我们要保存的路径"))  //若这个路径不存在时会创建 具体复习文件那块
        //      return “OK”;
        //      }
        //      继续回到 请求/响应头
        //      请求头:Cookie 响应头 :Set-Cookie
        //      重点:cookie和session机制
        //      前提:一开始设置的http协议是无状态的协议:当服务器处理的请求响应很多时,这些属于那个用户发起的,服务器不知道(只知道当前这次请求的具体内容)
        //      例子:某人(A)开了一家店,A及较特殊,神魔都记不住,只能记忆一个客户进来提出购买服务 然后服务结束的过程
        //      当A接待的客户比较多时,A就不知道谁是谁
        //      矛盾:HTTP协议本身的无状态+实际需求是需要通过不同请求直接维护状态的,所以引出了解决方案 :Cookie(Http 协议标准) session
        //      Cookie:就是A发给每个客户的一个凭证,客户有保存这个凭证的责任,也有下次购买服务携带这个凭证的责任(相当于理发店的会员卡)
        //      发凭证:从服务器到客户端,所以肯定是在响应中的                   cookie:凭证的意思
        //      Set-Cookie:设置凭证
        //      携带凭证:从客户端到服务器,所以肯定是在请求中
        //      Cookie:携带凭证跟在后面
        //      @Controller
        //      public class CookieController {
        //      //专门用来发凭证(Cookie)的
        //
        //      GetMapping("/set-cookie")
        //      public void setCookie(HttpServletRequest request ,HttpServletResponse response){
        //      Cookie cookie=new Cookie(name,“ygs”);
        //       Cookie cookie=new Cookie(course,“java”);
        //        Cookie cookie=new Cookie(today,"2022-8-17");
        //
        //      response.addCookie(cookie1);
        //
        //      response.addCookie(cookie2);
        //
        //      response.addCookie(cookie3);
        //
        //
        //      response.setCharacterEncoding("utf-8");
        //      response.setContentType("text/plain");
        //
        //      //写响应内容
        //      response.getWriter().println("cookie 设置成功,请观察开发者工具的 网络面版 和 应用面板")
        // }
        // }
        // 之后客户端在发送请求就会携带之前的cookie(在请求头中 key-value)
        //
        //
        // 服务器有设置凭证的职责,具体在HTTp中的表现
        //   在http响应中台添加Set-Cookie的响应头,value为 <key value>形式的数据
        //
        //   客户端有保存cookie的职责 具体在HTTp中的表现
        //   根据响应的set-cookie的value 将cookie信息保存到 内存or 文件  所以cookie的范围是浏览器范围(内存)
        //
        //  大部分cookie是各个版本的浏览器自己去保存的,不会在不同浏览器之间共享
        // Cookies=设置的时候可以设置过期时间,过期后失效了 服务器行为
        //   设置域 默认cookie是本域限制的
        //   当时可以通过设置,可以让子域生效
        //   设置生效路径,默认情况是本域所有资源可用,但可以设置
        //
        //   客户端在发送请求时,都有携带本网站所有cookie的职责 (如果没有就不带)
        //   Http请求中,添加cookie头,后续的value是cookie中的key value
        //
        //   服务器具体去利用cookie
        //   Coolie[] cookie=request.getCookies();
        //
        //   如果完全信任cookie,因为cookie保存在客户端(谁都可以看,谁都可以改),则碰到恶意用户 或 恶意程序修改了cookie(或伪造cookie)都有问题
        //
        //   解决办法:拆开保存数据,把敏感数据保存到服务器内部,cookie中只携带不敏感信息---session就此而生(会话)
        //   session是保存在服务器的,专属每次会话的一组数据,可以跨请求访问到
        //   通常,session中保存的数据可以视为name(key)-value
        //   一般利用cookie设置session-id,这样,客户端和服务端之间任然使用cookie机制,只是cookie只传递id,大头数据全部保存在服务器
        //
        //    HttpSrevletRequest类下的
        //    HttpSession getSession(Boolean create);       HttpSession session=request.getSession(flag);
        //    用户获取本次请求的session数据是根据
        //    1.请求中的cookie是否有session-id?            判断是否有id
        //    2.如果有session-id,对应的房间是否存在?         判断id是否是假的
        //    3.既有session-id,对应的房间也存在,返回这个房间
        //    参数Boolean create的作用:
        //    1.如果能获取   HttpSession对象,则create为true/false都没有区别
        //    2.如果没有获取到HttpSession对象,则
        //    create==true  创建一个新的房子 (HttpSession对象)并且返回
        //    create==false  不创建,返回null
        //
        //
        //
        //  HttpSession session=request.getSession(true);
        //  session.setAttrribute("name","value");
        //  session.getAttrribute("name");
        //
        // HttpSrevletRequest类下有
        // request.getSession() 等价于  request.getSession(true)
        //
        //
        // Cookie和Session在实际场景中最常见的应用--在线用户管理(如何再一次HTTP请求-响应中判断用户是否登录 以及登录用户是谁)
        // 和cookie session有关系的:用户登录 用户推出 获取等前登录用户的信息:当前用户保存在session中
        //
        // 用户注册:为用户信息做持久化保存--在数据库维护一条信息 等登录是来证明你是你
        // 常见的信息:  1.用户名+密码   2.手机号加手机验证码    3.qq 微信 支付宝
        // 用户名+密码的方案:
        // 用户表 :uid (唯一标识符)    用户名(需要保持唯一性)  密码(暂时明文)
        //
        // Connection对象(mysql),线程不安全的,原则上与许一个Connection执行多条SQL 性能更好
        // prepareStatement对象(mysql) 线程不安全,原则上可多次绑定参数,多次执行的
        // ResultSet对象是一次性的
        //
        // @RequestParam("username") String username   作为形参出现  获取get请求的以“username”为参数的值
        // TODO:TODO的在该注释处有功能代码代编写 就一个高亮显示
        //
        // HttpSession session =request.getSession();
        // //由于之前没有session的
        // //所以内部的工作是
        // //1.创建一个随机的session-id
        // //2.为这个session-id分配一个HttpSession对象 Map<String,Object>结构
        // //3.响应中设置Cookie (Set-Cookie),JSESSIONID=session-id
        //
        // 获取当前登录用户信息,判断用户是否在线 如果在线 当前用户是谁
        // 实际要做的判断:
        // 请求响应中若没有session对象,就说明没有经力过登录,就是用户未登录 因为登陆了一定会保存session 并且session有值
        //
        // session是保存在服务端 浏览器范围有效
        // 我们可以在cookie中得到sessionid从而session(JSessIONID)
        // 当程序退出后,进程结束,上一个保存的session就没了  比如我打开QQ(用户上线) 进程开启 退出QQ(用户下线) 进程关闭
        // cookie和session的作用域一样
        //
        // HTTP是基于TCP的一种应用层协议 是一种不安全的协议 可以植入广告 木马
        // 网络安全 核心是加密
        // 明文数据  -》  密文
        // 支持反向
        // 密文数据 -》明文数据
        //
        // 现代密码学:明明白白地告诉别人我在传输数据,你就是破解不了
        // HTTPS:http的安全版本 也是应用层的
        //
        //
        //   .   ____          _            __ _ _
        //  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
        // ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
        //  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
        //   '  |____| .__|_| |_|_| |_\__, | / / / /
        //  =========|_|==============|___/=/_/_/_/
        //  :: Spring Boot ::                (v2.7.3)
        //
        //
        // spring是神魔?         spring 框架
        // 围绕spring框架构造的一套java生态下的事实标准的解决方案
        //
        // 长用 spring Framework+ spring boot
        // -------------------------------------------------------------------------------------------------------------------
        // loc  控制反转     DI:依赖注入
        //
        // 对象依赖其他对象少                                 对象依赖其他对象多
        // 直接new 需要的对象                                商品经济出现:
        //                                                 买方:      买方    买卖方
        //
        //
        // 依赖:对象之间有关系
        // ioc 容器:放的是对象 就是一个对象市场 里面放置带出售的对象
        // 作为对象的买方:我们只在代码中声明我们依赖(买)那些类型的对象,最终对象是被Spring loc注入给我们(对象送货上门)
        // 作为对象的卖方:
        // 1.自己生产好,再去卖
        // 2.将生产对象的配方(告诉spring使用什么方法去实例化对象)告诉loc容器 最终售卖的对象有ioc生产[使用更多]
        //
        // 新建项目:只勾选lombok(不勾不让过)
        //
        // bean:就是spring售卖的对象
        //
        // spring落实起来
        // 1.基于xml的配置做法【学习阶段更方便 时间很少使用 实践中很乱】
        // 创建一个.xml格式的文件
        // 在主方法中定义一个 loc容器
        // //FileSystemXmlApplicationContext is ApplicationContext 接口的一个子类
        // //ApplicationContext 代表ioc 容器的抽象
        // FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("xxx.xml的路径");
        // //我们希望spring帮我们售卖person对象,并且生产过程也交给spring来完成
        // //那么xxx.xml中写:
        // 在<beans>中添加
        // <bean id="wodea" class="从java下的类的路径(不包含java)"> </bean>
        // //因为没写构造方法,默认调用无参,并将生产好的对象以wodea来买
        // 作为纯粹的买家去买:Object obj=context.getBean("wodea");
        // System.out.println(obj.getClass().getCanonicalName)  //打印真实的对象类型
        // 卖方可以指定在实例化时调用那个构造方法
        // <bean id="money" class="xxx.money"> <constructor-arg value="1998"/> </bean>  //1980为构造方法的参数
        //
        // 产生依赖关系:
        // 即使卖方有是买方
        // 1>.以构造方法参数的形式注入
        // <bean id=“zoo” class="sdsa.zoo">
        // //通过 ref 指定注入这个构造过程的需要用到的另一个对象 Monkey 对象的id  value 是直接值
        //  <constructor-arg ref="monkey"/> </bean>
        //  2>.以setter方法参数的形式注入
        //  <bean id="monkey-hill" class="com.ygs.web1">    name是monkey,就会调用monkey属性的设置 按照java的规范 会调用
        //  <proprety name="monkey" ref="some-animal"/>      MonkeyHill的setter方法 所以回去调用setMonkey方法,使用
        //                                                      ref="some-animal" some-animal是之前的monkey的id  意为买一个 monkey
        // </bean>
        //
        // public class MonkeyHill{
        // public MonkeyHill{
        //    }
        //    public void setMonkey(Monkey monkey){
        //    }
        // }
        //
        //
        // <bean id="city1" class="com.ygs.web1.CityFactory" factory-method="create">    使用Spring 调用CityFactory下的Create()   得到一个City对象 命名为city1
        //
        //     public class CityFactory{
        //     public static City create(){
        //     return new City();
        //     }
        //     }
        //     Universe对象:
        //     1.先通过构造方法注入的方式,实例化出一个universeFactory对象
        //  <bean id="universe-factory" class="com.peixincgen.ioc.universeFactory">
        //       <constructor-arg ref="monkey"/> </bean>
        //        <constructor-arg ref="monkey2"/> </bean>
        //         <constructor-arg ref="monkey3"/> </bean>
        //          <constructor-arg ref="monkey4"/> </bean>
        //
        //
        // </bean>
        //    通过指定universeFactory的createUniverse方法实例工厂方法 自己new出universe
        //    <bean id="universe" factory-bean="universe-factory" factory-method="createUniverse">
        //    依赖注入要发生在买/卖方
        //
        //  通过beans标签Spring可得到 map<String id,String className>   对象的名字与配方
        //  然后全部bean实例化  通过反射机制
        //  得到类似的结构: Map<id,obj> beanMap    在loc贩卖
        //  context.getbean(id)  得到特定的bean
        //           //  37 2022-8-22-ioc视频中有反射机制去模拟spring处理
        //
        //
        // java中的对象从语法上来讲是平等的,但由于作用不同,使用场景不同,使得对象出现了不同的分类
        // 对象:属性 方法
        //
        // 只关注属性 【数据对象】                           (大部分类在中间)          只关注方法(过程)【过程对象】
        //      <----------------------------------------------------------------------->
        // 进行用户登录的例子:
        // User 类                                                          UserService
        // int uid                                               根据用户名+密码进行查询 返回登录成功
        // String username
        // String password
        // 只关注属性 【数据对象】                                                           只关注方法(过程)【过程对象】
        // 更注重tiString() equals()                                                越容易以单例模式存在
        // hashCode() Comparable/comparator的重写                                   因为没属性,定义一个或多个没区别,那就定义一个
        // 素材的抽象:                                                               工业厂房的抽象
        // 水 糖 工业色素 瓶子 饮料 贴牌                                           1.糖+水+色素-》饮料 Comtroller
        //                                                                    2.饮料+贴牌 》可以包装的饮料  view
        //                                                                    MVC:Moudle view Controller
        //                                                                    最原生主义下的MVC
        //                                                                    view:用来处理展示相关流程的对象 【过程对象】
        //                                                                    controller:用来处理数据加工流程的对象【过程对象】
        //                                                                    model:
        //                                                                    1.数据对象 [理解方式1]
        //                                                                    2.获取数据对象的【过程对象】    [理解方式2 ]
        //
        //  java视角下的各种不同类型的对象
        //   【过程对象】:
        //   controller/控制器 :
        //       主要HTTP资源相关的工作
        //       1.读取用户参数 判断合法性
        //        2.HTTP响应 :状态码 重定向 响应头
        //   Service/服务
        //   1.从各种数据聚合的整理 变换结构等
        //
        //   数据对象
        //   model、entity、dataobject
        //   -------------------------------------------------------------------------------------------------------
        //   SSM:
        //   controller/service/Mapper(Repoisotry 、DAO)
        //   entity viewObject                        过程对象才会交给spring去管理----spring管理对象默认是单例的
        //   ----------------------------------------------------------------------------------------------------------
        //    2.基于注解:
        //    通过为要注册的类上面添加注解 + spring在启动过程中扫描包下的所有类来确定那些类要被spring管理 (根据有无注解)
        //    在beans标签中加<context:component-scan base-package="com.peixinchen.io2"/>
        //   Component:组件
        //   添加@ Component后 Spring启动扫描这里会将其进行管理起来(会被new)
        //   @Component
        //   public class A{
        //   }
        // 如何进行类的注册
        // 被以下注解修饰即可
        // @component 组件
        // @Controller  控制器
        // @Service   服务
        // @Repository 仓库 从数据库 进行数据读取
        // @Configuration  配置
        //
        // 一般来说用上面那个标签修饰都行,更建议使用@Configuration修饰
        // @Configuration
        // public class AppConfig{
        // public AppConfig(){}
        //
        // @bean           //由于这个类已经被注册到spring中+这个方法被@bean 修饰,所以会把”你好“注册到spring中
        // public String peixinchen(){
        // return “你好”
        // }
        // }
        //
        // 使用bean :全是注入的方式(前提是使用bean的类先被spring管理起来)
        // @Autowried
        // 1.构造方法注入  用@Autowried  不写也行 但建议都带上
        // 2.setter方法注入   用@Autowried修饰setter方法
        // 3.直接属性注入   用@Autowried修饰属性
        // 如果用@Autowried修饰一个有参数的构造方法,则默认调用此构造方法
        // 加上@Autowried 会被调用 也就是以这种方式得到我需要的零件 而不是将方法注入到spring
        //
        // 如果使用人家提供的main方法 默认是从main方法所在类的包下 例如com.ygs.web1
        // public static void main(String[] args) {
        //        SpringApplication.run(Web1Application.class, args);
        //        可以获取loc
        //        ApplicationContext context=SpringApplication.run(Web1Application.class, args);  Web1Application:main的类名
        //                                                            com.ygs.web1包下的范围
        //     }
        //     @conponent等也可以通过@Autowried注入
        //
        //
        // 配置文件:软件的设置
        // java中默认的配置文件格式:prorerties格式
        // 基本构造:key:value  sposad=abc   //abc为字符串,且不用""扩
        // key是分段的
        //
        // 我们希望可以在我们的代码中去读取配置文件,这样我们的代码逻辑可以根据配置进行调整
        // 方式1.springboot中已经注册好了一个叫做envirment的对象 咱可直接用这个对象
        // 这个对象提供了类似于map一样的读取配置的能力 根据key得到value
        // Environment environment =context.getBean(Enviroment.class);
        // String value=environment.getProperty("spring.banner.image.location");   //得到application.properties下的spring.banner.image.location"
        // 方式2.springboot提供了@value的注解,可直接将配置项的值注入 +spring表达式(SpEl)
        // @bean
        // public DataSource(@Value("${spring.datasource.url}") String v1,   //spring.datasource.url写在application.properties下
        // Value("${spring.datasource.username}") String v2,
        // Value("${spring.datasource.password}") String v3,){
        //
        //
        // }
        //
        // 方法三
        // 合适配置项特别多的情况,将其封装为一个对象
        // @component
        // @ConfigyrationProperties("bit.hjb.pxc")   //设置以bit.hjb,pxc下的所有配置(添加)  在application.properties-
        // {
        // private String name;
        // private String name1;
        // //必须要有set方法                              //bit.hjb.pxc.name=name
        // public void setName(name){
        // name=name;
        // }
        // }
        //
        // spring提供了另一种配置文件的格式:YAML
        // 1.等价于;bit.hjb.age
        // 每层有缩进(两个空格)   :后面有一个空格
        // bit:
        //   hjb:
        //     age: 3    //后面没有‘;’ 上一种格式也没有
        //
        // 日志:就是记录 (打印信息:时间 线程 类。。。)
        // 一般使用 slf4j   org.slf4j
        // lombok使用前提:1.导入包 2.下载lombok插件 (我都有)
        // @Data:此注解包含以下注解:@ToString、@EqualsAndHashCode、@Getter、@Setter、@RequiredArgsConstructor
        // @Slf4j:lombok自动导入日志
        //
        // 对象代理:
        // interface Flyable{
        // void fly()
        // }
        // class bird implements Flyable{   ...
        // public void fly(){}
        // }
        // Flyable flyable=new Bird();
        // 对象代理:中间人 ,调用flyable的 fly()方法,优先将调用给代理对象,然后代理去进行调用处理 然后再去调用bird的fly方法
        // 比如 你向老师查一些东西,通常是想班长查的,班长去和班主任交流
        // public class BirdProxy implements InvocationHandler{
        // private final Bird bird=new Bird();
        // @Override
        // public Obiect invoke(object proxy,Method,object[] args)throws Throwable{
        // method.invoke(bird);//调用bird对象的fly方法
        // return null;
        // }
        //
        // public class FlyableFactory{
        // public static Flyable cerate(){
        // Flyable instance=new Bird();
        // return instance;
        // }
        //
        // public static Flyable createWithProxy(){
        //
        // BirdProxy proxy=new BirdProxy();
        // //经过一套流程,弄出来了可以被Flyable 接口指向的对象(代理对象)
        // Object o=Proxy.newProxyInstance(
        // Flyable.class.getClassLoader(),
        // new Class[]Flyable.class,
        // proxy);
        // return (Flyable)o;
        // }
        // }
        // 要是有对象代理
        // Flyable flyable=FlyableFactory.createWithProxy();
        // 调用createWithProxy()-->得到一个java官方提供的Proxy对象-->得到bird
        // 代理完全可以拿钱不办事(拟造一个假的给你)
        // 对象代理+ioc组合一起:
        // 作为对象的买方不用关心买到的是啥,只要能满足我的需求即可  也不知道买的是啥,
        // 通过@Bean 修饰的方法 会将返回值注册到ioc里
        // 通过类名.class拿到  类名.class也可以拿到@component等的对象
        // 2022-8-25 有东西 很难  mybites的原理 动态代理 有些人家分装的代理 不一定要知道人家咋做的,我知道他是干啥的就行 很急就不用看了
        //
        //  mybatis:
        //
        // 从创建项目中勾选:关系型数据库--》spring data jdbc :勾了之后就会自建一个datasource
        //           勾选:myBatis Framework
        //           勾选:MYSQL Driver
        //           勾选:lombok
        //           此datasource 默认使用HikariDataSource:自带线程池,性能较好
        //
        // myBatis Framework:就是引入 MyBatis框架 方便使用sql操作
        // MYSQL Driver 引入mysql-connector-java 提供JDBC访问的底层支持
        // 需要配置配置文件:在application.yml中配置
        // 配置数据库:
        // spring:
        //   datasource:
        //     url: aaaaaaaaaaaaaaaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        //     username: root
        //     password: 123456
        //
        // @Mapper //来自Mybatis的注解 意思是让 myBatis 为这个接口创建一个代理对象
        //     public interface UserMapper{
        //     @select("select语句") //传入select 返回结果  如果不是查询 则返回值要变
        //       List<User> selectUser();
        //     }
        // myBatis:1.动态拼接SQL  2.ORM:把表映射成类,把表中记录映射成一个对象
        //
        // myBatis偏向于ORM,但对动态SQL支持力度还不错
        //
        // 我们作为myBatis的用户,提供
        // 1.接口,接口中写明了各种各样的方法
        // 2.需要告诉myBatis接口中的这些方法应该:
        //   1.需要执行的是那条SQL
        //   2.参数化的SQL 如何匹配方法中的参数和SQL里的参数
        //   3.查询出来的表结果,如何和方法的返回值结(一般是对象)一一映射
        // 3.myBatis根据我们提供的,提供好一个对象代理,完成jdbc的整套流程
        // 有两种方案:1).注解  2)XML方式
        // 参数化SQL的解决:
        // 引入 @Param(org.apache.ibatis.annotations)
        //     @select("select.......where username = #{u}")
        //       List<User> selectUser(@Param("u") String username);   意思是:用username替换#{u}  //会防止sql注入
        //
        //   方法的返回值类型:             对象实际上就是一个有约束的map                  属性名称
        // 1.返回一条记录                   User             等价于                       Map<String,Obiect>
        // 2.返回一批                     List<User>          等价于                    List<Map<String,Obiect>>
        //
        // XML方式
        // 在yml下配置:
        // mybatis:
        //   # *代表从孩子层
        //   # **代表所有子孙
        //   # 找以 .xml结尾的文件 认为是mybatis 的XML 配置
        //   # classpath:可以简单理解从resources目录开始算起
        //   mapper-locations: classpath:mapper/**-mappeer.xml   //例如有一个 yse-mapper.xml就可以被识别
        //   look 2022-8-25 .png
        // <mapper namespace="com.ygs1.web1.UserMapper"
        // <insert id="addUser">
        // insert into users (username,password) values (#{username},#{password})
        // </insert></mapper>
        // @Repository //可以不写 插入时
        // @Mapper //写在接口上
        // public interface UserMapper{
        // int addUser (User user);
        //注解:
        // @Select("insert into users (username,password) values (#{username},#{password})")
        // int adduser2(User user);
        //
        //
        //
        //
        //
        // // 如果返回值和表中的值不一样  表中的值用别名 修改成一致
/*
动态sql:
<insert id ="addUserBatch" userGenerateKey="true" keyProrerty="uid" KeyClounm="uid">  //自增uid
  insert into users (username,password) values
 <foreach collections="list" item="xxx" speparator=", ">
 (#{xxx.username},#{xxx.password})
 </foreach>
<insert/>
int addUserBatch(@Param("list")) List<User> userlist);//使用(@Param("list"))要在sql userlist.属性
<delete id="deleteBatch">
detele from  users where uid in (
<foreach collections="uidlist" item="xxx" speparator=", ">
#{uid}
 </foreach>)
 </delete>
 //查出uidlist的所有用户
 <select id="selectlist" resultType="com.peixinchen.mybatis.demo.User">
 select uid,usemname,passwoawd from user,where uid in (
 <foreach collections="uidlist" item="xxx" speparator=", ">
#{uid}
 </foreach>

 )


*/
  /*
  AOP面向切面编程
  OOP面向对象编程

    AOP面向切面编程
  和使用者相关的概念:
  1.这个公共业务代码是什么,验证登录,统计耗时
  2.这个业务和那些具体业务产生关系:验证登录 发布消息
  3.发生关系的具体时机是什么:之前 之后

开启AOP 在pom.xml中:   springframework-boot       <artifactId>spring-boot-starter-parent-aop</artifactId>
  从query—string(GET /POST)或请求体(application/x-www-form-urlencoded 的post请求)
  换而言之,从form表单读取数据
  使用@RequestParam,修饰的形参,几种形式:
  @RequestParam String xxx;   读取form表单中name为xxx的值
  String xxx;                        读取form表单中name为xxx的值
  @RequestParam(value="yyy") String xxx;   读取form表单中name为yyy的值  必须传yyy否则400错误
   @RequestParam(value="yyy",required=false) String xxx;   读取form表单中name为yyy的值  不必须传
   int xxx;   读取form表单中name为xxx的值,转换成int 如果转换失败 也是400错误

   直接定义一个请求参数对象来接受,springmvc回将请求对象构造对象@model
   public String getParamObject(SomeClass s)    SomeClass是我们定义的对象
   {}
   一般除了重定向 (转发应该也有) 资源都使用@ResponseBody


@RequestBody可以接受JSON格式
public String getJSON (@RequestBody SomeClass someClass ){}

@GetMapping("/csdn/{username}")
public String (@getPathVariable("username") String name ){}

或者 @GetMapping("/csdn/{username}/{abc}")

上传文件:    public string (@RequestPart("文件名") MultipartFile xx){}

@Value("{app.upload-dir-root}") :读取配置文件下的值 application.properties
 public string (@RequestPart("文件名") MultipartFile xx){
 String uuid;
 File dest;
 dest=new File(uploadDirRoot,uuid);   //uploadDirRoot路径  创建一个件  uploadDirRoot,uuid 路径+名字
 xx.transferTo(dest);                 //文件拷贝

 除此之外,请求参数可以有:
1.HttpSevletRequest 对象  等同于sevlet中的 request的用法
2.HttpSession         等价于先获取 HttpSevletRequest 然后调用 request.getSession() 一般不用
3.@RequestHeader 注解修饰的对象,获取请求头
 }

 动态资源的返回值分两类:
 1.方法被@RequestBody修饰   这个方法返回值是完整的响应体的内容
 返回String Content-type:text/html
 返回其他对象: content-type:application/json
 2.方法没有被@RequestBody修饰     这个方法返回值应该被当做ModelAndView的逻辑处理 一般是view-nmae
     返回名字 名字对应到 classpath:templates/某个模板文件的名称
     返回String&&"redirect:"后面根url
     返回String&&"forward:"后面根url

    @RequestBody修饰类是整个类下的所有方法都是 @RequestBody

   @RestController=  @RequestBody+@Controller

   在类上使用@RequestMapping("/user")  所有的RequestMapping有统一的前缀/user
  */






}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值