Cookie和Session的弊端
Cookie是客户端机制,Session是服务端机制
Cookie存在的问题是,他可以被伪造
Session存在的区别是分布式问题。
一、响应
@Control,@RestController
1.Controller的源码,代表什么意思
第一个Target后面的Type 表示注解后面可以接类,假如后面有method表示后面可以接方法
第二个是表示这个注解的生命周期
Spring这个东西可以被称为一个容器,可以简简单单加几个注解即可。
Controller的意思是告诉Spring,帮助我们管理这个代码,我们后续访问时候,才能访问到。
@ResponseBody告诉返回的是一个数据
@Control返回的是视图,随着前后端分离,后端开始不处理页面,就返回页面所需要的数据
@RestController=@Control+@ResponseBody的结果
2.返回数据 @Responsebody
可以修饰类,也可以修饰方法,修饰类的时候,表示这个类下的所有方法,返回的均是数据,修饰方法的时候,表示该方法返回的是数据,如果一个类的所有方法返回的都是数据,我们就把这个注解加在类上。
3.返回HTML片段
4.返回JSON
当接口返回的是String时,content-Type是text/html
当我们的接口返回的是对象时,content-Type application-JSON
5.那么假如我们使用集合会怎么样呢
设置状态码,虽然不影响展示,但是确实显示起来也就是401的情况。
@ResponseBody @RequestMapping("/setStatus") public String setStatus(HttpServletResponse response){ //状态码不影响页面的展示 response.setStatus(401); return "设置状态吗"; }
2.我们可以看到默认的情况下,它是text/html,设置成application/json
@ResponseBody // @RequestMapping(value = "/r1",produces = "application/json;charset=utf-8") @RequestMapping(value="/r1") public String r1(HttpServletResponse response){ return "{'OK':1}"; }
我们可以通过指定的方式,来让这个变成application,可以设置返回类型。当然也不能强制转化成json不然也会报错。
consumes:指定处理请求的提交内容类型,例如application/json,text/html;如果指定
application/json(更像是一个限制)
produces:设置返回的内容类型,仅当request请求头中的类型中包含该指定类型才返回。
@ResponseBody @RequestMapping(value = "/r1",produces = "application/json;charset=utf-8") //@RequestMapping(value="/r1") public String r1(HttpServletResponse response){ return "{'OK':1}"; }
设置标头(看响应,多个myhead)
@ResponseBody @RequestMapping(value = "/r1",produces = "application/json;charset=utf-8") //@RequestMapping(value="/r1") public String r1(HttpServletResponse response){ //设置header的方法 response.setHeader("myhead","myhead"); return "{'OK':1}"; }
前后端结合小案列
前端的一个计算器代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="calc/sum" method="post"> <h1>计算器</h1> 数字1:<input name="num1" type="text"><br> 数字2:<input name="num2" type="text"><br> <input type="submit" value=" 点击相加 "> </form> </body> </html>
对应着后端代码其中,name1的命名和name2命名,和form中name 保持一致
package com.example.demo; import org.springframework.boot.context.config.InactiveConfigDataAccessException; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/calc") @RestController public class CalcController { @RequestMapping("/sum") public String sum(Integer num1,Integer num2){ Integer sum=num1+num2; return "计算结果:"+sum; } }
开发中程序报错,如何定位问题呢?
通过日志 (打印日志,指的是在最开始就打印一个这种***看你的后端代码能否在执行之前打印出来,从而判定是不是后端有毛病) 请求是否到达后端
1.前端:f12看控制台
2.后端:看接口,控制台日志
还可以我们手动去测试接口,假如这样好使,就说明前端的问题。
我们在访问前端的过程时候,前面8080后面什么也不用接,直接加路径名字即可。
以下是两个前端代码
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>用户登录首页</title> </head> <body> 登录人: <span id="loginUser"></span> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script> //页面加载的时候,就应该去调用后端的请求了,ajax的执行顺序,看你写到哪里,上一个那个是在函数里面才被调用,但是这个是直接到了script也就是一加载,就会被调用的 $.ajax({ url:"/user/getUserInfo", type:"get", success :function (username){ //放值就用text,不是放值,就去用html $("#loginUser").text(username) } }) </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <h1>用户登录</h1> 用户名:<input name="userName" type="text" id="userName"><br> 密码:<input name="password" type="password" id="password"><br> <input type="button" value="登录" onclick="login()"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script> //form表单使页面进行跳转,页面跳转要搭配后端来进行页面跳转的,因为我们后端不再搭配前端来进行显示了。所以用ajax完成页面的请求 function login() { console.log("登录...")//这种就属于是加日志,它是为了检测是否到达了这个函数 $.ajax({ url:"/user/login", type:"post", data:{ "userName":$("#userName").val(), "password":$("#password").val() }, success:function (result){ if(result){ location.href="/index.html" //location.assign(); }else{ alert("密码错误"); } } }); } </script> </body> </html>
package com.example.demo; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @RequestMapping("/user") @RestController public class UserController { @RequestMapping("/login") /*1.登录接口 /user/login userName=?password=? 接口返回:校验成功/失败 true密码正确 false密码错误 */ public Boolean login(String userName, String password, HttpSession session) { // if(userName==null||userName.length()==0||password==null||password.length()==0){ // return false; // } /* 上面的过于麻烦,Spring为我们提供来一个好东西,去判断这个字符串有没有长度 */ if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) { return false; } //进行用户名和密码的校验,假装账号等于admin,密码也是admin if ("admin".equals(userName) && "admin".equals(password)) { //设置session session.setAttribute("username", "admin"); return true; } return false; } /* 获取用户的登录信息 /user/getUserInfo 接口名称:当前登录用户的名称 */ /*@RequestMapping("/getUserInfo") public String getUserInfo(HttpSession session){ //从session中获取登入用户 String userName=(String) session.getAttribute("username"); return userName; }*/ //下面这种方式更加规范,因为上面那种假如说没有session会自动创建一个session,但是假如说session创建了,他也是空的不影响问题。 @RequestMapping("/getUserInfo") public String getUserInfo(HttpServletRequest request){ //Session获取登录用户,下面这个方式就是,假如session不为空,那么他也就不会去创建一个session HttpSession session= request.getSession(false); String username=null; if(session!=null){ username=(String) session.getAttribute("username"); } return username; } }