SpringBoot基础设置笔记

目录

1 设置配置文件路径和文件名
2 设置扫描的基础包
3 使用log4j2
4 单元测试
5 FreeMarker配置和使用
6 整合MyBatis + MySql
7 添加拦截器
8 RestTemplate使用HTTPS通信(双向认证)

1 设置配置文件路径和文件名

需要在启动前进行配置:

@SpringBootApplication
public class Main
{
    public static void main(String[] args)
    {
        SpringApplication application = new SpringApplication(Main.class);
        Map defaultMap = new HashMap();
        defaultMap.put("spring.config.location", "classpath:/conf/");
        defaultMap.put("spring.config.name", "kysvc");
        application.setDefaultProperties(defaultMap);
        application.run(args);
    }
}

2 设置扫描的基础包

在启动类前添加以下注解即可

@ComponentScan(basePackages={包名})

3 使用log4j2

需要要将默认的logging配置关闭,并加入log4j2的依赖


    org.springframework.boot
    spring-boot-starter-web
    
        
            org.springframework.boot
            spring-boot-starter-logging
        
    
    ${springboot.version}

 
 

    org.springframework.boot
    spring-boot-starter-log4j2
    ${springboot.version}

之后在设置中指定配置文件地址,例如,配置文件为main/resources/conf文件夹下的log4j2.xml,则需要如下配置:

logging.config=classpath:conf/log4j2.xml

4 单元测试

添加依赖,注意junit版本必须在4以上



    org.springframework.boot
    spring-boot-starter-test
    ${springboot.version}
    test


    junit
    junit
    4.12
    test

SpringBoot 1.4版本起,单元测试的设置有了一些变化,原来的@SpringApplicationConfiguration注解被废弃,改为使用@SpringBootTest注解[1]
在单元测试时,可通过使用@TestPropertySource注解来指定测试用的配置文件路径[5]
单元测试范例:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Main.class)
@WebAppConfiguration
@TestPropertySource(locations="classpath:conf/test.properties")
public class UserCtrlTest
{
    private MockMvc mvc;
    private static final Gson GSON = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
     
    @Before
    public void setup()
    {
        mvc = MockMvcBuilders.standaloneSetup(new UserCtrl()).build();
    }
     
    @Test
    public void sampleTest() throws Exception
    {
        MvcResult result = mvc.perform(MockMvcRequestBuilders.get("/user/test").accept(MediaType.APPLICATION_JSON)).andReturn();
        int status = result.getResponse().getStatus();
        Assert.assertTrue("错误,正确的返回值为200", status == 200);
        String content = result.getResponse().getContentAsString();
        Assert.assertTrue("数据不一致", "test123".equals(content));
    }
     
    @Test
    public void userInfoTest() throws Exception
    {
        String name = "kevin";
        String idcard = "420102199901011234";
        String tel = "13700000000";
         
        User user = new User(name, idcard, tel);
        String uri = "/user/" + name + "/" + idcard + "/" + tel;
         
        MvcResult result = mvc.perform(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON)).andReturn();
        int status = result.getResponse().getStatus();
        Assert.assertEquals(200, status);
        String userStr = result.getResponse().getContentAsString();
        Assert.assertEquals(GSON.toJson(user), userStr);
    }
}

5 FreeMarker配置和使用

添加依赖:



    org.springframework.boot
    spring-boot-starter-freemarker
    ${springboot.version}

添加配置:

#Freemarker
spring.freemarker.template-loader-path=classpath:pages/
spring.freemarker.suffix=.html
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html

上面的配置将模板路径指定到了pages文件夹下,并将模板后缀设置为了html(默认为ftl)
模板范例:




    

亲爱的${toUserName},你好!

${message}

祝:开心!
${fromUserName}
${time?date}

注意:为页面控制器添加注解时,要使用@Controller而非@RestController !
页面控制范例:

@Controller
public class PageCtrl
{
    @RequestMapping("/hello/{name}")
    public String hello(@PathVariable("name") String name, ModelMap model)
    {
        model.addAttribute("time", new Date()); 
        model.addAttribute("message", "今天的风儿有些喧嚣呢。"); 
        model.addAttribute("toUserName", name); 
        model.addAttribute("fromUserName", "Kevin Yang");
        return "hello";
    }
}

6 整合MyBatis + MySql

添加依赖:


    
    3.3.0
    1.3.0
    5.1.40
    
 


    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    ${mybatis-spring.version}


    mysql
    mysql-connector-java
    ${mysql-connector.version}

在启动类前添加注解设置需要扫描的mapper包

@MapperScan(basePackages={"com.ky.tests.*.mapper"})

在配置文件中配置jdbc

#JDBC
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/ky_time_log?useUnicode=true&autoReconnect=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

注:有关DataSource的拓展设置
在官方默认的文档[0]中,没有记录一些拓展的配置,例如包括maxWait、maxActive等连接池相关的配置,这些配置都通过代理模式实现在DataSourceProxy这个类中,在配置文件中直接进行相应的配置即可,例如:
spring.datasource.maxActive=5
spring.datasource.maxWait=60000
具体原理参考:Spring-Boot: How do I set JDBC pool properties like maximum number of connections?
注意:如果使用tomcat连接池以外的连接池,可能需要其他连接池定制的设置

其余设置和接口实现与原spring mvc + mybatis相同

7 添加拦截器

首先实现一个拦截器类,重载HandlerInterceptorAdapter类,或实现HandlerInterceptor接口:

public class UserInterceptor extends HandlerInterceptorAdapter
{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        String auth = request.getParameter("auth");
        if("kevin".equals(auth))
        {
            return true;
        }
        else
        {
            throw new AuthFailure("认证失败", null);
        }
    }
}

然后借助spring boot的自动配置机制,注册实现的拦截器:

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter
{
    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
        registry.addInterceptor(new UserInterceptor());
    }
}

注意:根据官方文档说明,在使用了自动配置的注解重载WebMvcConfigurerAdapter后,会与@EnableWebMvc注解有一定冲突,详见spring boot adding http request interceptors

8 RestTemplate使用HTTPS通信(双向认证)

首先生成服务端和客户端的密钥库和信任库,导出各自的证书,并互相添加到对方的信任库中
服务端配置:

server.ssl.enabled=true
server.ssl.key-store=classpath:cert/kysvc.p12
server.ssl.key-store-password=cking123
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=kysvc
server.ssl.trust-store=classpath:cert/kytrust.jks
server.ssl.trust-store-password=cking123
server.ssl.trust-store-type=jks
server.ssl.client-auth=NEED

客户端配置和实现:
参考RestTemplate实践,在客户端实现一个自定义SSL配置类,并在其中定义好生成ClientHttpRequestFactory所需的Bean:

@Configuration
public class SSLConfiguration
{
    @Bean
    public RestOperations restOperations(ClientHttpRequestFactory clientHttpRequestFactory) throws Exception
    {
        return new RestTemplate(clientHttpRequestFactory);
    }
    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient)
    {
        return new HttpComponentsClientHttpRequestFactory(httpClient);
    }
     
    private KeyStore _parseKeyStore(String keystorePath, String passwd) throws Exception
    {
        String keyStoreType = "jks";
        if(keystorePath.endsWith(".p12"))
        {
            keyStoreType = "pkcs12";
        }
         
        KeyStore keystore = KeyStore.getInstance(keyStoreType);
        if(keystorePath.startsWith("classpath:"))
        {
            keystorePath =  ClassLoader.getSystemResource("").getFile() + keystorePath.substring(keystorePath.indexOf(":") + 1);
        }
        FileInputStream instream = new FileInputStream(new File(keystorePath));
        try
        {
            keystore.load(instream, passwd.toCharArray());
        }
        finally
        {
            instream.close();
        }
        return keystore;
    }
    @Bean
    public HttpClient httpClient(@Value("${https.client.keystore.file}") String keyStoreFile,
                    @Value("${https.client.keystore.pass}") String keyPass,
                    @Value("${https.client.truststore.file}") String trustStoreFile,
                    @Value("${https.client.truststore.pass}") String trustPass) throws Exception
    {
        KeyStore keyStore = _parseKeyStore(keyStoreFile, keyPass);
        KeyStore trustStore = _parseKeyStore(trustStoreFile, trustPass);
         
        SSLContext sslcontext = SSLContexts.custom()//
                        .loadKeyMaterial(keyStore, keyPass.toCharArray())//
                        .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
                        .build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1.2" }, null,
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
    {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

然后根据上述实现,在配置文件中添加相应配置:

#Client
https.client.keystore.file=classpath:cert/httpstest.p12
https.client.keystore.pass=cking123
https.client.truststore.file=classpath:cert/truststore.jks
https.client.truststore.pass=cking123

配置好后即可借助RestTemplate对服务端进行https调用:

@RestController
@RequestMapping(path = "/invoke")
public class SvcInvoker
{
    @Autowired
    ClientHttpRequestFactory factory; //这个资源在上面的SSLConfiguration中已有定义
     
    @RequestMapping(path = "/timelog")
    public @ResponseBody String getTimeLogs()
    {
        RestTemplate involker = new RestTemplate(factory);
        return involker.getForEntity("https://172.17.99.187:8443/timelog/all", String.class).getBody();
    }
}

参考链接

[0] Appendix A. Common application properties(官方配置范例)
[1] Spring Boot 1.4 单元测试
[2] Spring Boot-构建一个复杂的RESTful API及单元测试
[3] RESTful API 设计指南
[4] Spring boot 使用FreeMarker模板
[5] Override default Spring-Boot application.properties settings in Junit Test
[6] Testing improvements in Spring Boot 1.4
[7] Spring Boot 整合 MyBatis
[8] spring boot adding http request interceptors
[9] Spring MVC HandlerInterceptor Annotation Example with WebMvcConfigurerAdapter
[10] RestTemplate实践

你可能感兴趣的:(SpringBoot基础设置笔记)