Giter Site home page Giter Site logo

xkcoding / spring-boot-demo Goto Github PK

View Code? Open in Web Editor NEW
32.1K 1.0K 10.7K 13.86 MB

🚀一个用来深入学习并实战 Spring Boot 的项目。

Home Page: https://parg.co/UZM

License: MIT License

Java 86.76% HTML 8.88% FreeMarker 0.11% Dockerfile 0.07% PLpgSQL 1.27% TSQL 2.79% Lua 0.12%
java in-action demo web spring spring-boot spring-boot-2 spring-boot-demo xkcoding

spring-boot-demo's Issues

actuator不能加入其它Controller

我在启动类加入hello world,

@SpringBootApplication
public class SpringBootDemoActuatorApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemoActuatorApplication.class, args);
	}

	@RequestMapping("/hello")
	public String sayHello(){
	    return "Hello";
    }

}

浏览器打开相关链接会强制跳转到登录界面(Bug?),登录后也报错
在actuator的mappings里面也找不到相关API

AppLog 记录http请求日志的方式,可以考虑用这种方式

@Component
@Slf4j
@Data
public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered {

    private boolean logSwitch = false;  // 这里是开关,自行控制改成true;显示打印日志

    private String checkPath = "/check_is_online";  // 监控接口,不加日志

    private static final String IGNORE_CONTENT_TYPE = "multipart/form-data";

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE - 10;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        /**
        if (!isRequestValid(request)) {
            filterChain.doFilter(request, response);
            return;
        }
         **/

        if (!(request instanceof ContentCachingRequestWrapper)) {
            request = new ContentCachingRequestWrapper(request);
        }

        if (!(response instanceof ContentCachingResponseWrapper)) {
            response = new ContentCachingResponseWrapper(response);
        }
        int status = HttpStatus.INTERNAL_SERVER_ERROR.value();
        long startTime = System.currentTimeMillis();
        try {
            filterChain.doFilter(request, response);
            status = response.getStatus();
        } finally {
            String path = request.getRequestURI();
            if (logSwitch && !Objects.equals(path, checkPath)
                    && !Objects.equals(IGNORE_CONTENT_TYPE, request.getContentType())) {

                String requestBody = IOUtils.toString(request.getInputStream(), "UTF-8");
                log.info(requestBody);
                //1. 记录日志
                HttpTraceLog traceLog = new HttpTraceLog();
                traceLog.setPath(path);
                traceLog.setMethod(request.getMethod());
                long latency = System.currentTimeMillis() - startTime;
                traceLog.setTimeTaken(latency);
                traceLog.setTime(LocalDateTime.now().toString());
                traceLog.setParameterMap(request.getParameterMap());
                traceLog.setHeaderMap(getHeaders(request));
                traceLog.setStatus(status);
                traceLog.setRequestBody(getRequestBody(request));
                traceLog.setResponseBody(getResponseBody(response));
                log.info("http trace log: {}", JSON.toJSONString(traceLog));
            }
            updateResponse(response);
        }
    }

    private boolean isRequestValid(HttpServletRequest request) {
        try {
            new URI(request.getRequestURL().toString());
            return true;
        } catch (URISyntaxException ex) {
            return false;
        }
    }

    private String getRequestBody(HttpServletRequest request) {
        String requestBody = "";
        ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
        if (wrapper != null) {
            try {
                requestBody = IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
            } catch (IOException e) {
                // NOOP
            }
        }
        return requestBody;
    }

    private String getResponseBody(HttpServletResponse response) {
        String responseBody = "";
        ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
        if (wrapper != null) {
            try {
                responseBody = IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding());
            } catch (IOException e) {
                // NOOP
            }
        }
        return responseBody;
    }


    private Map<String,String> getHeaders(HttpServletRequest request) {
        Map<String,String> headers = Maps.newHashMap();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            headers.put(key, request.getHeader(key));
        }
        return headers;
    }

    private void updateResponse(HttpServletResponse response) throws IOException {
        ContentCachingResponseWrapper responseWrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
        Objects.requireNonNull(responseWrapper).copyBodyToResponse();
    }


    @Data
    private static class HttpTraceLog {

        private String path;
        private Map<String, String[]> parameterMap;
        private Map<String, String> headerMap;
        private String method;
        private Long timeTaken;
        private String time;
        private Integer status;
        private String requestBody;
        private String responseBody;
    }

}

zookeeper 分布式锁报错

`2019-05-31 17:27:41.247 ERROR 10732 --- [ain-EventThread] org.apache.zookeeper.ClientCnxn : Error while calling watcher

java.lang.IncompatibleClassChangeError: Inconsistent constant pool data in classfile for class org/apache/curator/framework/CuratorFramework. Method lambda$postSafeNotify$0(Ljava/lang/Object;)V at index 99 is CONSTANT_MethodRef and should be CONSTANT_InterfaceMethodRef
at org.apache.curator.framework.CuratorFramework.postSafeNotify(CuratorFramework.java:344) ~[curator-framework-4.1.0.jar:4.1.0]
at org.apache.curator.framework.recipes.locks.LockInternals$2.process(LockInternals.java:69) ~[curator-recipes-4.1.0.jar:4.1.0]
at org.apache.curator.framework.imps.NamespaceWatcher.process(NamespaceWatcher.java:77) ~[curator-framework-4.1.0.jar:4.1.0]
at org.apache.zookeeper.ClientCnxn$EventThread.processEvent(ClientCnxn.java:525) ~[zookeeper-3.5.4-beta.jar:3.5.4-beta-7f51e5b68cf2f80176ff944a9ebd2abbc65e7327]
at org.apache.zookeeper.ClientCnxn$EventThread.run(ClientCnxn.java:500) ~[zookeeper-3.5.4-beta.jar:3.5.4-beta-7f51e5b68cf2f80176ff944a9ebd2abbc65e7327]
`

[FEATURE]利用Spring缓存注解如@Cacheable操作redis,后台查看redis中的数据,value是乱码,建议序列化为 json

描述问题

xk,你好;
spring-boot-demo-cache-redis 项目中,利用Spring缓存注解如 @Cacheable 操作redis,后台查看redis中的数据,key没有乱码,但是value是乱码;
利用 RedisTemplate 操作value没有乱码。

期待的结果

期望利用Spring缓存注解如@Cacheable操作redis,查看redis中的数据,value不是乱码。

截屏或录像

image

关于spring-boot-demo-properties项目获取不到pom的值

需要在pom文件下加入以下代码

	<build>
		<finalName>spring-boot-demo-properties</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
	</build>

另外,获取pom的值也可以使用${}方式

application:
  name: prod环境 @artifactId@
  version: prod环境 ${project.version}
developer:
  name: prod环境 xkcoding
  website: prod环境 http://xkcoding.com
  qq: prod环境 237497819
  phone-number: prod环境 17326075631

Add examples.

Should we consider add example to each topics?
How to use it and best practice to use it!

I.e: for helloworld demo the example would be http://localhost:8080/demo/hello?who=ibrahim

请问完全按照你的demo写,发现报这个错误,请问是什么原因造成的?

描述问题

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'propertyController' defined in file [/Users/zhangliang/Desktop/**/spring2019.9/springbootdemoproperties/target/classes/com/example/springbootdemoproperties/controller/PropertyController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationProperty': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'application.name' in value "${application.name}"
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1341) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1187) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) [spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]

期待的结果

请尽量清晰精准地描述你所期待的结果。

截屏或录像

如果可能,请尽量附加截图或录像来描述你遇到的问题。

其他信息

请提供其他附加信息帮助我们诊断问题。

[FEATURE] 作者能否在demo里尽量加一些controller展示用法

首先感谢作者的辛勤付出,写出这么多的demo。我的意见是:对于新手来说,有的demo里面只是集成了个功能模块,但是似乎并没有展示怎么简单的使用,比如mybatis,我觉得如果demo里加一个controller 来展示一下如何使用会更好。

多项目 日志动态精确 控制

目标:
1、项目提供restful接口,动态 修改 线上项目的日志级别,动态 生成添加 新的包路径logger 记录包日志 (支持log4j2,logback).
2、可以动态指定 某个用户的 userId ,让该用户所有操作行为日志全为debug(可指定)级别,且把该日志全单独写入一个独立文件,可以根据userId 查询某用户所有操作日志(有页面可以操作)
3、一个请求中,异步任务也需能支持日志动态改变,需设置线程池支持。
4、多个项目,使用共享redis 支持。一处操作,所有关联项目都同时同步 更改日志的操作

多模块问题

请问一下在spring-boot-dubbo中是如何创建子模块下的子模块,我本地一创建,就会报错。只能穿件一层子模块

Spring-boot-demo中的基于Guava实现的限流,多方法注解不能限流

描述问题

Spring-boot-demo中的spring-boot-demo-ratelimit-guava项目,我如果把注解RateLimiter注解到不同的方法上面,就不能对不同的方法实现不同令牌的限流。

期待的结果

在不使用Redis的情况下,能不能就通过Guava的RateLimiter方法实现单服务不同方法的不同令牌的限流。

邮件发送demo

我将邮箱配置换成自己的163邮箱之后为什么发送出去之后会变成垃圾邮件发送给对方?
前两天测试demo上的邮箱可以正常发送,现在demo上的邮箱不能使用了。
多谢!

[BUG]spring-boot 使用 2.1.8.RELEASE 启动 spring-boot-demo-task-quartz 项目,项目报错,无法启动。

描述问题

我在使用 spring-boot 的 2.1.8.RELEASE 开发定时任务功能时,使用数据库保存定时任务配置,启动项目过程中会报错,无法启动项目(错误日志在下面)。从网上没有查到类似的错误,然后将 spring-boot 的版本切换到 2.1.7.RELEASE 可以正常启动项目。怀疑是不是我项目配置有问题,我就下载了 spring-boot-demo-task-quartz 项目,将 spring-boot 版本修改为2.1.8.RELEASE 项目无法启动,报错内容相同,修改版本为 2.1.7.RELEASE 项目可以正常启动。

错误日志

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration$JdbcStoreTypeConfiguration$QuartzSchedulerDependencyConfiguration': Unexpected exception during bean creation; nested exception is java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:528) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) [spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) [spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) [spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
	at com.xkcoding.task.quartz.SpringBootDemoTaskQuartzApplication.main(SpringBootDemoTaskQuartzApplication.java:25) [classes/:na]
Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
	at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724) ~[na:1.8.0_171]
	at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531) ~[na:1.8.0_171]
	at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) ~[na:1.8.0_171]
	at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) ~[na:1.8.0_171]
	at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) ~[na:1.8.0_171]
	at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) ~[na:1.8.0_171]
	at java.lang.reflect.Executable.declaredAnnotations(Executable.java:599) ~[na:1.8.0_171]
	at java.lang.reflect.Executable.declaredAnnotations(Executable.java:597) ~[na:1.8.0_171]
	at java.lang.reflect.Executable.getAnnotation(Executable.java:570) ~[na:1.8.0_171]
	at java.lang.reflect.Method.getAnnotation(Method.java:622) ~[na:1.8.0_171]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.lambda$determineCandidateConstructors$0(AutowiredAnnotationBeanPostProcessor.java:249) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:410) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:417) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:389) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:248) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1269) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1184) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	... 14 common frames omitted

期待的结果

在 spring-boot 的 2.1.8.RELEASE 版本下需要如何配置 quartz 才可以正常使用 quartz。

[FEATURE]可否考虑集成SpringBatch

你在什么场景下需要该功能?

进行数据迁移,例如,mysqlA->mysqlB中。或者从文本类文件写入数据到mysql中

描述可能的解决方案

SpringBatch进行处理

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.