神刀安全网

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<String, Object> defaultMap = new HashMap<String, Object>();         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的依赖

<dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-web</artifactId>     <exclusions><!-- 去掉默认日志配置 -->         <exclusion>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-logging</artifactId>         </exclusion>     </exclusions>     <version>${springboot.version}</version> </dependency>    <!-- log4j2依赖 --> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-log4j2</artifactId>     <version>${springboot.version}</version> </dependency> 

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

logging.config=classpath:conf/log4j2.xml 

4 单元测试

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

<!-- 单元测试 --> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-test</artifactId>     <version>${springboot.version}</version>     <scope>test</scope> </dependency> <dependency>     <groupId>junit</groupId>     <artifactId>junit</artifactId>     <version>4.12</version>     <scope>test</scope> </dependency> 

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配置和使用

添加依赖:

<!-- 模板渲染 --> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-freemarker</artifactId>     <version>${springboot.version}</version> </dependency> 

添加配置:

#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)
模板范例:

<!DOCTYPE html> <html> <body>     <h4>亲爱的${toUserName},你好!</h4>     <p style="color: blue;">${message}</p>     祝:开心!     </br> ${fromUserName}     </br> ${time?date} </body> </html> 

注意:为页面控制器添加注解时,要使用@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

添加依赖:

<properties>     <!-- 其他配置省略 -->     <mybatis.version>3.3.0</mybatis.version>     <mybatis-spring.version>1.3.0</mybatis-spring.version>     <mysql-connector.version>5.1.40</mysql-connector.version> </properties>       <!-- 数据库 --> <dependency>     <groupId>org.mybatis.spring.boot</groupId>     <artifactId>mybatis-spring-boot-starter</artifactId>     <version>${mybatis-spring.version}</version> </dependency> <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>${mysql-connector.version}</version> </dependency> 

在启动类前添加注解设置需要扫描的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基础设置笔记

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址