jjzjj

SpringBoot前后端交互

暴走的小帅 2023-08-30 原文

1.SpringBoot概述:

          Spring Boot 是在 spring 框架基础之上开发的框架, 其设计目的是用来简化应用的初始搭建以及开发过程。虽然 spring 的组件代码是轻量级的,但它的配置却是重量级的, 即使 spring 引入了注解功能,但是仍然需要编写大量的模板化配置文件. 项目的依赖管理也是一件耗时耗力的事情,在环境搭建时,需要分析要导入大量库的坐标,而且还需要分析导入与之有依赖关,一旦选错依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度,    Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开 发者体验的工具. 

2.交互

        1.前端发送一个登陆请求

 submitForm(form) {
         this.$refs[form].validate((valid) => {
           if (valid) {
			   this.$http.post("admin/loginCtl/login",this.form).then((resp)=>{

2.后端根据前端地址接受请求

@RequestMapping(path = "/admin/loginCtl")
public class LoginController {
 @RequestMapping(path = "/login")
    public CommonResult login(@RequestBody Admin admin2){

(1)跨域的配置

@Configuration
加入@Configuration 注解,表明这就是一个配置类。
@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        //1,允许任何来源
        corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
        //2,允许任何请求头
        corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
        //3,允许任何方法
        corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
        //4,允许凭证
        corsConfiguration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(source);
    }
}

(2)验证token(token拦截器)

先进行配置

@Configuration
public class WebConfig implements WebMvcConfigurer{

	public void addInterceptors(InterceptorRegistry registry) {
		InterceptorRegistration inter =  registry.addInterceptor(new TokenInterceptor());
		inter.addPathPatterns("/admin/**"); //管理员需要拦截过滤地址
		inter.excludePathPatterns("/admin/loginCtl/login");//放行地址

再验证token,  登录时前端没有token,所以要对登录请求放行,登录成功后生成token再返回给前端保存在请求头中,再次交互时进行验证

public class TokenInterceptor implements HandlerInterceptor {

    //预处理
    //当请求经过映射处理器检测对应的控制器是存在,判断该请求可以进入拦截器,执行调用
    //返回true,继续向下执行
    //返回false,请求不在向下执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        boolean res = JWTUtil.verify(token);
        if (!res){
            CommonResult commonResult = new CommonResult(202,"token验证失效");
            JsonMapper jsonMapper = new JsonMapper();
            String json = jsonMapper.writeValueAsString(commonResult);
            response.getWriter().print(json);
        }
        return res;
    }
}

(3)application.yml yml 是 YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心,时springboot的配置文件

server:
  port: 8080
#spring相关配置
spring:
  #配置数据库连接信息,生成默认的数据源队形,生成jdbcTemplate,事务管理功能初始化
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai
    username: root
    password: 12121212
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource #指定数据源类型,还需要创建对象
    initialSize: 5 #配置数据库连接池相关的配置
    maxActive: 20



  main:
    allow-circular-references: true  #开始支持spring循环依赖
#myatis配置  创建sqlsessionFactory
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
mybatis:
    type-aliases-package: com.ffyc.news.model
    mapper-locations: classpath:mappers/*Mapper.xml
    configuration: #mybatis配置  setting配置
         map-underscore-to-camel-case: true
         cache-enabled: true
         log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

由Druid数据源来进行读取

/*
 @Configuration  配置注解  表示此类是springBoot项目中一个配置类,sprngboot启动时会扫描
*/
@Configuration
public class DruidDataSourceConfig {

	/*
	   @Bean  == <bean  id=""  class="">  作用在方法上,方法中会产生一个对象,最终把此对象交给spring容器
	 */
	@Bean
	@ConfigurationProperties(prefix = "spring.datasource")
	public DataSource druid() {
		//创建对象,从yml配置文件读值,赋值
		DruidDataSource  dataSource = new DruidDataSource();
		//dataSource.setInitialSize();
		return dataSource;//此方法产生的当对象最终返回并交给spring容器去管理
	}
}

3.交互完成后将结果返回给前端

前端将返回的数据接收并进行相应的处理,其中携带的token也被aoixs保存在请求头中

//axios 请求拦截 
axios.interceptors.request.use(config =>{
	//向请求头中添加一个自定义请求头
	config.headers.token = sessionStorage.getItem('token'); 
	   return config; 
})

3.完整的登录前后端交互

1.前端发送登录请求,将用户输入的账号密码发送到后端

  methods: {
       submitForm(form) {
         this.$refs[form].validate((valid) => {
           if (valid) {
			   this.$http.post("admin/loginCtl/login",this.form).then((resp)=>{
				   console.log(resp);
				   if(resp.data.code==200){
					   //sessionStorage.setItem浏览器提供的一个会话级别的存储空间,浏览器关闭后立刻清除
					   sessionStorage.setItem("account",resp.data.data.account);
					   sessionStorage.setItem("token",resp.data.data.token);
					   //localStorage.setItem("key","value");//长久保存
					   this.$router.push("/main");
				   }else if(resp.data.code==201){
					   this.$message({message:resp.data.message,type:'warning'});
				   }else{
					   this.$message.error(resp.data.message);
				   }
			   })
              
           } 
         });
       },
       resetForm(form) {
         this.$refs[form].resetFields();
       }
     }

2.web层(接收.处理,响应)

@RestControllerAdvice
@RestController
@RequestMapping(path = "/admin/loginCtl")
public class LoginController {

    //static Logger logger = LoggerFactory.getLogger(LoginController.class);
    @Autowired
    LoginService loginService;
    @RequestMapping(path = "/login")
    public CommonResult login(@RequestBody Admin admin2){
        //将日志信息写入到一个文件中,长久保存
       // logger.debug("进入到后端登录功能:account={},password={}",admin2.getAccount(),admin2.getPassword());
        admin2.setPassword(DigestUtils.md5DigestAsHex(admin2.getPassword().getBytes()));
        Admin admin = loginService.login(admin2);
       // logger.debug("登录成功:account={},password={}",admin.getAccount(),admin.getPassword());
        if(admin!=null){
            CommonResult commonResult = new CommonResult(admin,200,"保存成功");
            return commonResult;
        }
        CommonResult commonResult1 = new CommonResult(null,201,"保存失败");
        return commonResult1;
    }

3.service层(业务上的一些处理)

@Service(value = "loginService")
@Transactional
public class LoginService {

    @Resource
    LoginDao loginDao;

    public Admin login(Admin admin2){
        Admin admin1 = loginDao.login(admin2);
        String token = new JWTUtil().token(admin1.getId(),admin1.getAccount(),admin1.getType());
        admin1.setToken(token);
        return admin1;
    }

    public List<Menu> findmenus(String token) {
        DecodedJWT decodedJWT = JWTUtil.getTokenInfo(token);
        Integer id = decodedJWT.getClaim("id").asInt();
        Integer type = decodedJWT.getClaim("type").asInt();
        List<Menu> list = loginDao.findmenus(id,type);
        return list;
    }
}

4.model类(封装一些用户的信息或管理员的信息)

@ApiModel(value = "管理员实体类",description = "管理员实体类2")
@Data
public class Admin {
    @ApiModelProperty(value = "管理员主键")
    private Integer id;
    private String account;
    private String password;
    private Integer type;
    private String token;
    private String gender;
    private String phone;
    private Admin admin;//操作人
    private int pageNum;//当前页数
    private int pageSize;//页数大小
    @JsonFormat(pattern = "yyyy-MM-dd  HH:mm:ss", timezone = "GTM+8")
    private Date operTime;
    private List<Role> roles;
    private Integer[] roleIds;
}

5.dao层(与数据库进行交互)

@Repository(value = "loginDao")
   public interface LoginDao {

    public Admin login(Admin admin);

有关SpringBoot前后端交互的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  2. ruby - 在 ruby​​ 中的字符串前后添加空格? - 2

    我想在随机字符串前后添加一个空格。我试过使用"Random_string".center(1,"")但它不起作用。谢谢 最佳答案 我发现这是最优雅的解决方案:padded_string="#{random_string}"走简单的路没有错。 关于ruby-在ruby​​中的字符串前后添加空格?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/3357897/

  3. ruby - 如何在子类中的方法前后运行代码? - 2

    我的第一个想法是这样的:classAbstractBuilderattr_reader:time_takendefbuild_with_timerstarted_at=Time.nowbuild@time_taken=Time.now-started_atenddefbuildraise'Implementthismethodinasubclass'endendclassMyBuilder我怀疑有更好的方法可以提供更好的灵active,例如理想情况下,我想在MyBuilder的实例上调用“build”而不是“build_with_timer”,并且始终记录执行时间。我确实考虑过使用al

  4. springboot定时任务 - 2

    如果您希望在Spring中启用定时任务功能,则需要在主类上添加 @EnableScheduling 注解。这样Spring才会扫描 @Scheduled 注解并执行定时任务。在大多数情况下,只需要在主类上添加 @EnableScheduling 注解即可,不需要在Service层或其他类中再次添加。以下是一个示例,演示如何在SpringBoot中启用定时任务功能:@SpringBootApplication@EnableSchedulingpublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.ru

  5. 基于SpringBoot的线上日志阅读器 - 2

    软件特点部署后能通过浏览器查看线上日志。支持Linux、Windows服务器。采用随机读取的方式,支持大文件的读取。支持实时打印新增的日志(类终端)。支持日志搜索。使用手册基本页面配置路径配置日志所在的目录,配置后按回车键生效,下拉框选择日志名称。选择日志后点击生效,即可加载日志。windows路径E:\java\project\log-view\logslinux路径/usr/local/XX历史模式历史模式下,不会读取新增的日志。针对历史文件可以分页读取,配置分页大小、跳转。历史模式下,支持根据关键词搜索。目前搜索引擎使用的是jdk自带类库,搜索速度相对较低,优点是比较简单。2G日志全文搜

  6. springboot使用validator进行参数校验 - 2

    1.依赖导入org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-validation2.validation常用注解@Null被注释的元素必须为null@NotNull被注释的元素不能为null,可以为空字符串@AssertTrue被注释的元素必须为true@AssertFalse被注释的元素必须为false@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值@D

  7. 停车系统源码-基于springboot+uniapp开源项目 - 2

    Iparking停车收费管理系统-可商用介绍Iparking是一款基于springBoot的停车收费管理系统,支持封闭车场和路边车场,支持微信支付宝多种支付渠道,支持多种硬件,涵盖了停车场管理系统的所有基础功能。技术栈Springboot,MybatisPlus,Beetl,Mysql,Redis,RabbitMQ,UniApp功能云端功能序号模块功能描述1系统管理菜单管理配置系统菜单2系统管理组织管理管理组织机构3系统管理角色管理配置系统角色,包含数据权限和功能权限配置4系统管理用户管理管理后台用户5系统管理租户管理多租户管理6系统管理公众号配置租户公众号配置7系统管理操作日志审计日志8系统

  8. ruby - 如何与 Ruby 中的 Perl 程序交互? - 2

    据我了解,在Ruby和Perl之间没有“桥梁”可以让您直接从Ruby调用Perl函数。据我了解,要从Ruby调用Perl程序,只需将其放在反引号中(即result=`./helloWorld.pl`)。但是,这不允许与Perl程序交互(即您不能与提示交互或提供输入)。我的问题如下:有没有什么方法可以从Ruby向Perl程序提供输入(除了参数)?Ruby和Perl之间没有桥梁,我错了吗?在导航提示时与程序的标准输入交互似乎是错误的方式,我正在处理的程序设计良好,并且具有包含适当Perl函数的库。 最佳答案 有Inline::Ruby模

  9. ruby - IRb:如何使用预加载类启动交互式 ruby​​ session - 2

    在我采用Ruby语言的过程中,我花了很多时间在IRb中。太棒了!但是,由于我不是很清楚它的功能,并且对Ruby仍然是个“笨蛋”,所以我想知道以下内容:如何在不重新启动IRb的情况下“刷新”session(或者这是不可能的)。如何配置IRb加载一堆源文件“hello.rb”和“hello_objects.rb”,即在启动时?我在这些方面投入了大量工作,如果知道加载这些类的速记,而无需再次为每个类手动键入“加载”,那就太好了。 最佳答案 我不确定是否可以“刷新”session。但是,您可以像这样加载您的类:irb-r'hello.rb'

  10. ruby - Lisp - 是否适合网络编程/应用程序(交互式)? ruby 的方式是? php的方式是? - 2

    Lisp是否适合Web编程/应用程序(交互式),就像ruby​​和php一样?需要考虑的事情是:易于使用可部署性难度(尤其是对于编程初学者而言)(编辑)在阅读PaulGraham'sessay之后,我特别提到了CommonLisp.将是我的第一门编程语言。在这方面。这样做合适吗?我听说Clojure的宏功能不如CommonLisp的强大,这就是我尝试学习Clojure的原因。它教授编程并且非常强大。 最佳答案 Lisp是一个语系,而不是单一的语言。为了稍微回答您的问题,是的,存在用于各种Lisp方言的Web框架,例如用于Common

随机推荐