【SpringMVC快速使用】1.@RestController @RequestMapping 2.logback的使用

news2025/7/6 3:46:57

背景:为何从这个最简单的 例子写起呢?

那是因为我们的管理后台之类的都是别人写的,我也听说了大家说:只用Post请求就足够了,但是却发现,在浏览器中测试时,默认是GET请求,如果直接写的@PostMapping,则提示此请求不支持。

有了SpringBoot,开发部署一个Web项目是非常加单的。对比ASP.Net Core 和go的繁琐(因为很多东西需要自己从头做),SpringBoot是做到了开箱即用,我们引入需要的starter,使用依赖注入即可引入我们需要的service类,结合dubbo,我们可以轻松的实现微服务(也就是这个接口的实现是别的服务做的)。不管是同步还是异步,都是非常的简单的。

1)我们的游戏服务器是从“平台”账号注册开始的,那么我们就从这里开始:

package com.example.springbootdemo.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("/account")
public class AccountController {

    /**
     * @param username
     * @param password
     */
    @RequestMapping("/register")
    public void register(String username, String password) {
        log.info("新用户注册,username={}, password={}", username, password);
    }
}

/*
2024-01-11T11:10:10.421+08:00  INFO 32040 --- [nio-8080-exec-5] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
2024-01-11T11:10:10.647+08:00  INFO 32040 --- [nio-8080-exec-6] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
2024-01-11T11:10:10.850+08:00  INFO 32040 --- [nio-8080-exec-7] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
2024-01-11T11:10:11.014+08:00  INFO 32040 --- [nio-8080-exec-8] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
2024-01-11T11:10:11.187+08:00  INFO 32040 --- [nio-8080-exec-2] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
2024-01-11T11:10:11.362+08:00  INFO 32040 --- [io-8080-exec-10] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
2024-01-11T11:10:13.562+08:00  INFO 32040 --- [nio-8080-exec-9] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
2024-01-11T11:15:47.588+08:00  INFO 32040 --- [nio-8080-exec-5] c.e.s.controller.AccountController       : 新用户注册,username="xx", password="aa"
*/

2)日志肯定是少不了的

在pom.xml中引入下logback日志包 // 注意:不要带版本号,不然打包时就会提示logback版本号冲突了,我们使用继承过来的版本即可

    <!-- log -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
<!--      <version>1.7.25</version>-->
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
<!--      <version>1.7.7</version>-->
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
<!--      <version>1.2.3</version>-->
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
<!--      <version>1.2.3</version>-->
    </dependency>

接着把zfoo的logback.xml粘贴过来放到resources下面即可:

<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="false" debug="false">

  <property name="LOG_HOME" value="log/"/>
  <property name="PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss} [%-5level] [%thread] %logger.%M\(%F:%line\) - %msg%n"/>
  <property name="PATTERN_CONSOLE" value="%d{yyyy-MM-dd HH:mm:ss} [%highlight(%-5level)] [%thread] %logger{30}.%M\(%F:%L\) - %msg%n"/>
  <!-- 负责写日志,控制台日志,会打印所有的包的所有级别日志 -->
  <appender name="zfoo_console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${PATTERN_CONSOLE}</pattern>
      <charset>UTF-8</charset>
    </encoder>
  </appender>

  <!-- debug日志,只有一个文件,只收集debug级别日志,每次启动会覆盖以前的debug日志 -->
  <appender name="zfoo_debug" class="ch.qos.logback.core.FileAppender">
    <file>${LOG_HOME}/debug.log</file>
    <!-- append: true,日志被追加到文件结尾; false,清空现存文件;默认是true -->
    <append>false</append>
    <encoder>
      <pattern>${PATTERN_FILE}</pattern>
      <charset>UTF-8</charset>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>debug</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender>

  <!-- info,warn,error级别的日志都会添加在info.log日志中 -->
  <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
  <appender name="zfoo_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_HOME}/info.log</file>

    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
      <!-- each file should be at most 100MB, keep 30 days worth of history, but at most 40GB -->
      <maxFileSize>100MB</maxFileSize>
      <maxHistory>30</maxHistory>
      <totalSizeCap>40GB</totalSizeCap>
    </rollingPolicy>

    <encoder>
      <Pattern>${PATTERN_FILE}</Pattern>
      <charset>UTF-8</charset>
    </encoder>

    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>info</level>
    </filter>
  </appender>

  <!-- 异步输出 -->
  <appender name="zfoo_async_info" class="ch.qos.logback.classic.AsyncAppender">
    <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
    <discardingThreshold>0</discardingThreshold>
    <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
    <queueSize>512</queueSize>
    <!-- 添加附加的appender,最多只能添加一个 -->
    <appender-ref ref="zfoo_info"/>
  </appender>

  <!-- 只收集error级别的日志 -->
  <appender name="zfoo_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_HOME}/error.log</file>

    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
      <maxFileSize>100MB</maxFileSize>
      <maxHistory>30</maxHistory>
      <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>

    <encoder>
      <Pattern>${PATTERN_FILE}</Pattern>
      <charset>UTF-8</charset>
    </encoder>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>error</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender>

  <!-- 根logger -->
  <root level="info">
    <appender-ref ref="zfoo_console"/>
    <appender-ref ref="zfoo_debug"/>
    <appender-ref ref="zfoo_async_info"/>
    <appender-ref ref="zfoo_error"/>
  </root>

  <logger name="ch.qos.logback" level="info"/>
  <logger name="org.springframework" level="info"/>
  <logger name="io.netty" level="info"/>
</configuration>

3)结合lombok的@Slf4j注解,我们可以很轻松打印的日志(想想go或者asp.net core的话,自己不是太熟悉,还是得折腾半天)

4)测试

浏览器中发起下请求: 

http://localhost:8080/account/register?username="xx"&password="aa"

注意从浏览器中粘贴下来可能不是这样子了,这是因为进行了编码

http://localhost:8080/account/register?username=%22xx%22&password=%22aa%22 

观察下idea下的日志,可以看出来这个日志是非常清楚的

时间,日志级别,线程,日志是从哪个类打印出的,跳转,信息等非常清楚

5)打包也很容易了开箱即用。 

-------------另外一个用到的-----------

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <property name="LOG_DIR" value="./logs"/>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
<!--      <pattern>[%-5level][%d{HH:mm:ss.SSS}][%thread][%logger{30}][%L] - %msg%n</pattern>-->
      <pattern>%d{yyyy-MM-dd HH:mm:ss} [%highlight(%-5level)] [%thread] %logger{30}.%M\(%F:%L\) - %msg%n</pattern>
    </encoder>
  </appender>

  <!-- perf4j -->

  <appender name="ROLLFILE"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_DIR}/game.log</file>
    <rollingPolicy
      class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_DIR}/game.%d{yyyyMMdd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>[%-5level][%d{HH:mm:ss.SSS}][%thread][%logger][%L] - %msg%n</pattern>
    </encoder>
  </appender>


  <appender name="MONITOR_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_DIR}/monitor.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_DIR}/monitor.%d{yyyyMMdd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>[%-5level][%d{HH:mm:ss.SSS}][%thread][%logger][%L] - %msg%n</pattern>
    </encoder>
  </appender>


  <appender name="PERF4J_ROLLFILE"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_DIR}/game-perf.log</file>
    <rollingPolicy
      class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_DIR}/game-perf.%d{yyyyMMdd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n%ex</pattern>
    </encoder>
  </appender>
  <appender name="PERF4J_STATISTICS"
    class="org.perf4j.logback.AsyncCoalescingStatisticsAppender">
    <appender-ref ref="PERF4J_ROLLFILE"/>
    <timeSlice>60000</timeSlice>
  </appender>


  <appender name="ASYNC_ROLLFILE" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="ROLLFILE"/>
    <queueSize>1024</queueSize>
    <maxFlushTime>3000</maxFlushTime>
  </appender>

  <appender name="DispatchSingleThreadMgr" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="MONITOR_INFO"/>
    <queueSize>1024</queueSize>
    <maxFlushTime>3000</maxFlushTime>
  </appender>

  <logger name="org.perf4j.TimingLogger" level="INFO" additivity="false">
    <appender-ref ref="PERF4J_STATISTICS"/>
  </logger>

  <logger name="com.elex.framework.core.thread.DispatchSingleThreadMgr" level="INFO" additivity="false">
    <appender-ref ref="DispatchSingleThreadMgr"/>
  </logger>

  <logger name="org.springframework" level="INFO" additivity="false"/>
  <logger name="org.apache.http.impl" level="INFO" additivity="false"/>
  <logger name="org.apache.ibatis" level="INFO" additivity="false"/>
  <logger name="org.apache.http" level="INFO" additivity="false"/>
  <logger name="org.mybatis" level="INFO" additivity="false"/>
  <logger name="org.apache.thrift" level="INFO" additivity="false"/>
  <logger name="org.mongodb" level="INFO" additivity="false"/>
  <logger name="org.apache.zookeeper" level="INFO" additivity="false"/>

  <logger name="com.elex.icefire.scene.object.SO_PlayerCity" level="warn"/>
  <logger name="com.elex.billion.icefire.way.service.FindWayWorker" level="off"/>
  <logger name="com.elex.icefire.scene.object.model.SceneMove" level="off"/>
  <logger name="com.elex.icefire.scene.AbstractScene" level="off"/>
  <logger name="com.elex.icefire.scene.object.AbstractSceneObject" level="off"/>
  <logger name="com.elex.icefire.scene.object.playerTroop.SO_PlayerTroop" level="off"/>
  <logger name="com.elex.icefire.scene.object.resource.SO_NormalResource" level="off"/>


  <root level="debug">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="ASYNC_ROLLFILE"/>
  </root>
</configuration>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1383272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文阅读】Consistency Models

文章目录 IntroductionDiffusion ModelsConsistency ModelsDefinitionParameterizationSampling Training Consistency Models via DistillationTraining Consistency Models in IsolationExperiment Introduction 相比于单步生成的模型&#xff08;例如 GANs, VAEs, normalizi…

自行车商城网站网页设计与制作web前端设计html+css+js成品。电脑网站制作代开发。vscodeDrea

【自行车商城网站网页设计与制作web前端设计htmlcssjs成品。电脑网站制作代开发。vscodeDrea】 https://www.bilibili.com/video/BV1wT4y1p7jq/?share_sourcecopy_web&vd_sourced43766e8ddfffd1f1a1165a3e72d7605

Docker五部曲之四:Docker Compose

文章目录 前言Compose应用程序模型Compose规范顶层属性servicenetworkvolumesconfigssecrets 环境变量.env文件environment属性主机shell中的环境变量 Profiles&#xff08;剖面&#xff09;启动剖面自动启动剖面和依赖项解析 多compose.yml文件共享与扩展构建规范构建属性 部署…

MySQL主从复制配置(双主双从)

一、架构规划 一主多从可以缓解读的压力&#xff0c;但是如果主宕机了&#xff0c;所有从都不能写了&#xff0c;因此我们配置双主双从。 1、规划图 master1和master2互为主从关系&#xff0c;slave1是master1的从&#xff0c;slave2是master2的从。 2、环境准备 准备四台机…

浅谈对Maven的理解

一、什么是Maven Maven——是Java社区事实标准的项目管理工具&#xff0c;能帮你从琐碎的手工劳动中解脱出来&#xff0c;帮你规范整个组织的构建系统。不仅如此&#xff0c;它还有依赖管理、自动生成项目站点等特性&#xff0c;已经有无数的开源项目使用它来构建项目并促进团队…

WEB服务器-Tomcat

3. WEB服务器-Tomcat 3.1 简介 3.1.1 服务器概述 服务器硬件 指的也是计算机&#xff0c;只不过服务器要比我们日常使用的计算机大很多。 服务器&#xff0c;也称伺服器。是提供计算服务的设备。由于服务器需要响应服务请求&#xff0c;并进行处理&#xff0c;因此一般来说…

浅谈缓存最终一致性的解决方案

浅谈缓存最终一致性的解决方案 作者&#xff1a;clareguo&#xff0c;腾讯 CSIG 后台开发工程师 来源&#xff1a;腾讯技术工程open in new window 到底是更新缓存还是删除缓存? 到底是先更新数据库&#xff0c;再删除缓存&#xff0c;还是先删除缓存&#xff0c;再更新数据…

(Java企业 / 公司项目)分布式事务Seata详解(含Seata+Nacos组合使用)(二)

一. Seata Server配置Nacos 什么是配置中心?配置中心可以说是一个"大货仓",内部放置着各种配置文件,你可以通过自己所需进行获取配置加载到对应的客户端.比如Seata Client端(TM,RM),Seata Server(TC),会去读取全局事务开关,事务会话存储模式等信息.Seata的配置中心…

PyTorch项目源码学习(3)——Module类初步学习

torch.nn.Module Module类是用户使用torch来自定义网络模型的基础&#xff0c;Module的设计要求包括低耦合性&#xff0c;高模块化等等。一般来说&#xff0c;计算图上所有的子图都可以是Module的子类&#xff0c;包括卷积&#xff0c;激活函数&#xff0c;损失函数节点以及相…

计算机缺失mfu140u.dll的5种解决方法,亲测有效

在计算机系统运行过程中&#xff0c;mfu140u.dll文件的丢失是一个较为常见的问题场景。这个动态链接库文件(mfu140u.dll)对于系统的正常运行具有关键作用&#xff0c;它的缺失可能导致相关应用程序无法启动或执行功能异常。具体来说&#xff0c;mfu140u.dll丢失的场景可能出现在…

QT上位机开发(QSS美化)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 我们早期学习过web开发的同学都知道&#xff0c;web开发有三个部分&#xff0c;分别是html、css和java script。其中html负责控件生成和布局&#…

基于Matlab/Simulink的MIL仿真验证解决方案

文章目录 需求追溯 虚拟环境 模型检查 仿真验证 测试报告 参考文献 针对模型开发阶段的ECU算法&#xff0c;可以很直接地将其与虚拟车辆模型连接起来&#xff0c;通过MIL对其进行验证和确认。可以在开发过程的早期检测到设计错误和不正确的需求&#xff0c;也有助于安全地…

DSL查询文档--各种查询

DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1查询所有 结果&#xff1a; 2全文检索&#xff08;full text&#xff09;查询 常见的全文检索查询包括&#xff1a; match查询&#xff1a;单字段查询 multi_match查询&#xff1a;多字段查询&#xff…

阿里云ingress配置时间超时的参数

一、背景 在使用阿里云k8s集群的时候&#xff0c;内网API网关&#xff0c;刚开始是用的是Nginx&#xff0c;后面又搭建了ingress。 区别于nginx配置&#xff0c;ingress又该怎么设置参数呢&#xff1f;比如http超时时间等等。 本文会先梳理nginx是如何配置&#xff0c;再对比…

AC修炼计划(AtCoder Beginner Contest 334)A~G

传送门&#xff1a;UNIQUE VISION Programming Contest 2023 Christmas (AtCoder Beginner Contest 334) - AtCoder A题是最最基础的语法题就不再讲解。 B - Christmas Trees 该题虽然分低&#xff0c;但我觉得还是很不错的。 给你 l 和 r &#xff0c;设满足题意的数字是x则…

TIFF转JPG助手:轻松批量转换,优化图片管理

在数字时代&#xff0c;图片已成为我们生活和工作中不可或缺的一部分。为了更好地管理和使用这些图片&#xff0c;我们需要一个强大的工具来帮助我们转换和优化图片格式。TIFF转JPG助手正是这样一款理想的解决方案 首先&#xff0c;我们进入首助编辑高手主页面&#xff0c;会看…

qayrup-switch开发文档

因为只是一个小组件,所以直接拿csdn当开发文档了 书接上文uniapp怎么开发插件并发布 : https://blog.csdn.net/weixin_44368963/article/details/135576511 因为我业没有开发过uniapp的组件,所以我看到下面这个文件还是有点懵的 也不清楚怎么引入, 然后去翻了翻官方文档,官方…

基于时域有限差分法的FDTD的计算电磁学算法-YEE网格下的更新公式推导

基于时域有限差分法的FDTD的计算电磁学算法&#xff08;含Matlab代码&#xff09;-YEE网格下的更新公式推导 参考书籍&#xff1a;The finite-difference time-domain method for electromagnetics with MATLAB simulations&#xff08;国内翻译版本&#xff1a;MATLAB模拟的电…

面试官问,如何在十亿级别用户中检查用户名是否存在?

面试官问&#xff0c;如何在十亿级别用户中检查用户名是否存在&#xff1f; 前言 不知道大家有没有留意过&#xff0c;在使用一些app注册的时候&#xff0c;提示你用户名已经被占用了&#xff0c;需要更换一个&#xff0c;这是如何实现的呢&#xff1f;你可能想这不是很简单吗…