東川印記

一本東川,笑看爭龍斗虎;寰茫兦者,度橫佰昧人生。

通过Intellij idea 2020 gradle 搭建 Spring Boot 基础学习demo 02 开始Controller

2020年10月12日星期一



水完上次那个webService,总感觉不太对,是不是也太麻烦了。。。。


然后找了下,可以直接访问到 controller。。。。

1,Controller 上线

依然是从Application开始

package dc.test.spring.boot2.sun;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 入口3,实现 直接访问controller
 *
 * @author senrsl
 * @ClassName: TestSunApplication
 * @Package: dc.test.spring.boot2.sun
 * @CreateTime: 2020/10/12 3:25 下午
 */
@SpringBootApplication
public class TestSunApplication {

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

}

然后,直接加个controller。。。。

package dc.test.spring.boot2.sun.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * http://localhost:8080/sun
 *
 * @author senrsl
 * @ClassName: Test01Controller
 * @Package: dc.test.spring.boot2.controller
 * @CreateTime: 2020/9/27 4:30 下午
 */
@RestController
public class TestSun01Controller {

    @RequestMapping("sun")
    public String sun() {
        return getClass().getSimpleName() + " from Sun";
    }

}

这时候,直接运行,竟然可以直接访问了。。。。

也不需要 注解去Scan啥的。。。。


结构如下:

SENRSL:boot2 senrsl$ tree sun/
sun/
├── TestSunApplication.java
└── controller
    └── TestSun01Controller.java

1 directory, 2 files
SENRSL:boot2 senrsl$


然后,get 跟post 都可以访问。。。。

SENRSL:Downloads senrsl$ curl -d 'name=bbbb&age=16' -X POST http://localhost:8080/sun
TestSun01Controller from Sun
SENRSL:Downloads senrsl$
SENRSL:Downloads senrsl$ curl 'http://localhost:8080/sun'
TestSun01Controller from Sun
SENRSL:Downloads senrsl$

这个简单了好多啊。。。。


2,@RestController默认返回 json结构

如果Controller类注解为 @RestController,会把返回的类默认返回为json字符串

结构如下

SENRSL:boot2 senrsl$ tree lee/
lee/
├── TestLeeApplication.java
├── controller
│   └── TestLeeController.java
└── domain
    └── LeeBean.java

2 directories, 3 files
SENRSL:boot2 senrsl$


主入口无变化,domain如下

package dc.test.spring.boot2.lee.domain;

/**
 * @author senrsl
 * @ClassName: LeeBean
 * @Package: dc.test.spring.boot2.lee.domain
 * @CreateTime: 2020/10/12 3:51 下午
 */
public class LeeBean {

    private long id;
    private String name;
    private int age;

    public LeeBean() {
    }

    public LeeBean(long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

然后 Controller如下:

package dc.test.spring.boot2.lee.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dc.test.spring.boot2.lee.domain.LeeBean;

/**
 * @author senrsl
 * @ClassName: TestLeeController
 * @Package: dc.test.spring.boot2.lee.controller
 * @CreateTime: 2020/10/12 3:51 下午
 */
@RestController
public class TestLeeController {

    @RequestMapping("getLeeBean")
    public LeeBean getLeeBean() {
        return new LeeBean(1L, "李啊", 100);
    }

}

domain需要写getter,不然会报

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class dc.test.spring.boot2.lee.domain.LeeBean]

运行效果:

SENRSL:Downloads senrsl$ curl http://localhost:8080/getLeeBean
{"id":1,"name":"李啊","age":100}
SENRSL:Downloads senrsl$ curl -X POST http://localhost:8080/getLeeBean
{"id":1,"name":"李啊","age":100}

SENRSL:Downloads senrsl$


看起来这个玩法,是现在更新语言的标配呢。。。。


3,增加filter

都是些老概念,老玩法,新工具。。。。


以前注册filter是在web.xml里逐个增加配置,使用Spring boot 可以通过xxxFilter注解、FilterRegistrationBean自定义注册等方式;

文件结构如下:

SENRSL:boot2 senrsl$ tree zhou/
zhou/
├── TestZhouApplication.java
├── configuration
│   └── TestZhouConfiguration.java
├── controller
│   └── TestZhouController.java
└── filter
    └── TestZhou01Filter.java

3 directories, 4 files
SENRSL:boot2 senrsl$

增加了TestZhouConfiguration文件和filter目录。

其中 TestZhou01Filter如下:

package dc.test.spring.boot2.zhou.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * filter来自javax.servlet包
 *
 * @author senrsl
 * @ClassName: TestZhou01Filter
 * @Package: dc.test.spring.boot2.zhou.filter
 * @CreateTime: 2020/10/12 4:19 下午
 */
public class TestZhou01Filter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println(getClass().getSimpleName() + " init() " + filterConfig + "  " + filterConfig.getFilterName() + " " + filterConfig.getInitParameter("testInit01"));
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        System.out.println(getClass().getSimpleName() + " doFilter() " + "request = " + request + ", response = " + response + ", chain = " + chain + ",requestUrl:" + req.getRequestURI());

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println(getClass().getSimpleName() + " destroy()");
    }
}

配置文件,TestZhouConfiguration如下:

package dc.test.spring.boot2.zhou.configuration;

import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import dc.test.spring.boot2.zhou.filter.TestZhou01Filter;

/**
 * @author senrsl
 * @ClassName: TestZhouConfiguration
 * @Package: dc.test.spring.boot2.zhou.configuration
 * @CreateTime: 2020/10/12 4:28 下午
 */
@Configuration
public class TestZhouConfiguration {

    @Bean
    public RemoteIpFilter testRemoteIpFilter() {
        return new RemoteIpFilter();
    }

    @Bean
    public FilterRegistrationBean testFilterRegistrationBean() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new TestZhou01Filter());
        //bean.addUrlPatterns("/zhou");  //过滤路径,只过滤/zhou,不过滤aaa/zhou或zhou/bbb
        bean.addUrlPatterns("/zhou/*");
        bean.addInitParameter("testInit01", "aaaaaaaaaaa");//这里设置,filter中filterConfig能取到
        bean.setName(TestZhou01Filter.class.getSimpleName());
        bean.setOrder(1);   //排序
        return bean;
    }

}

调用url,收到filter相关日志。。。。

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.4.RELEASE)

2020-10-12 16:38:24.108  INFO 32347 --- [           main] d.t.s.boot2.zhou.TestZhouApplication     : Starting TestZhouApplication on SENRSL with PID 32347 (/Users/senrsl/j2ee/Project/TestSpringBoot/spring_boot2/build/classes/java/main started by senrsl in /Users/senrsl/j2ee/Project/TestSpringBoot/spring_boot2)
2020-10-12 16:38:24.110  INFO 32347 --- [           main] d.t.s.boot2.zhou.TestZhouApplication     : No active profile set, falling back to default profiles: default
2020-10-12 16:38:24.574  INFO 32347 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-10-12 16:38:24.580  INFO 32347 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-10-12 16:38:24.580  INFO 32347 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.38]
2020-10-12 16:38:24.621  INFO 32347 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-10-12 16:38:24.621  INFO 32347 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 486 ms
TestZhou01Filter init() ApplicationFilterConfig[name=TestZhou01Filter, filterClass=dc.test.spring.boot2.zhou.filter.TestZhou01Filter]  TestZhou01Filter aaaaaaaaaaa
2020-10-12 16:38:24.724  INFO 32347 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-10-12 16:38:24.834  INFO 32347 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-10-12 16:38:24.841  INFO 32347 --- [           main] d.t.s.boot2.zhou.TestZhouApplication     : Started TestZhouApplication in 0.932 seconds (JVM running for 1.299)
2020-10-12 16:39:38.510  INFO 32347 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-10-12 16:39:38.511  INFO 32347 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-10-12 16:39:38.514  INFO 32347 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
TestZhou01Filter doFilter() request = org.apache.catalina.connector.RequestFacade@161b9acd, response = org.apache.catalina.connector.ResponseFacade@48b86f4f, chain = org.apache.catalina.core.ApplicationFilterChain@76899320,requestUrl:/zhou
TestZhou01Filter destroy()
2020-10-12 16:42:56.306  INFO 32347 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

Process finished with exit code 130 (interrupted by signal 2: SIGINT)


其中,启动时调用init,关闭时调用destroy,调用url时调用 doFilter()....

今天就水到这里,喝会茶准备下班!


--
senRsl
2020年10月12日15:31:46

没有评论 :

发表评论