提交 a310c195 编写于 作者: 武汉红喜's avatar 武汉红喜

whatsmars-boot-sample-swagger

上级 611e176a
......@@ -18,13 +18,11 @@ whatsmars-common | Utils公共模块
whatsmars-dubbo | 高性能分布式RPC框架
whatsmars-elasticjob | 分布式调度框架
whatsmars-elasticsearch | Elasticsearch
whatsmars-flink | 分布式流式计算框架
whatsmars-mq | 消息中间件RocketMQ,Kafka等
whatsmars-redis | Redis客户端简单封装
whatsmars-rpc | Transporter & Codec & Serialization
whatsmars-shardingsphere | 分布式数据库中间件
whatsmars-spring | Spring Framework
whatsmars-spring-boot | Spring Boot 实战
whatsmars-spring-boot-samples | Spring Boot Samples
whatsmars-spring-cloud | Spring Cloud 微服务生态
whatsmars-spring-data | Spring Data
......
......@@ -19,7 +19,6 @@
<modules>
<module>whatsmars-common</module>
<module>whatsmars-spring</module>
<module>whatsmars-spring-boot</module>
<module>whatsmars-elasticjob</module>
<module>whatsmars-dubbo</module>
<module>whatsmars-rpc</module>
......@@ -30,7 +29,6 @@
<module>whatsmars-spring-boot-samples</module>
<module>whatsmars-elasticsearch</module>
<module>whatsmars-zk</module>
<module>whatsmars-flink</module>
<module>whatsmars-spring-data</module>
<module>whatsmars-archetypes</module>
</modules>
......@@ -57,7 +55,6 @@
<mybatis.version>3.4.5</mybatis.version>
<mybatis-spring.version>1.3.1</mybatis-spring.version>
<rocketmq.version>4.5.1</rocketmq.version>
<swagger2.version>2.5.0</swagger2.version>
<zkclient.version>0.9</zkclient.version>
</properties>
......@@ -139,16 +136,6 @@
<artifactId>hessian</artifactId>
<version>${hessian.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
......
```shell
curl https://flink.apache.org/q/quickstart.sh | bash
```
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>whatsmars-parent</artifactId>
<groupId>org.hongxi</groupId>
<version>Rocket.S8</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>whatsmars-flink</artifactId>
<properties>
<flink.version>1.9.1</flink.version>
<scala.binary.version>2.11</scala.binary.version>
</properties>
<dependencies>
<!-- Apache Flink dependencies -->
<!-- These dependencies are provided, because they should not be packaged into the JAR file. -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
<!-- <scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<!-- <scope>provided</scope>-->
</dependency>
<!-- Add connector dependencies here. They must be in the default scope (compile). -->
<!-- Example:
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka-0.10_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
-->
<!-- Add logging framework, to produce console output when running in the IDE. -->
<!-- These dependencies are excluded from the application JAR by default. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-test-utils_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<!-- <scope>test</scope>-->
<type>test-jar</type>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package org.hongxi.whatsmars.flink.streaming;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.utils.ParameterTool;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;
import org.hongxi.whatsmars.flink.streaming.util.WordCountData;
/**
* Implements the "WordCount" program that computes a simple word occurrence
* histogram over text files in a streaming fashion.
*
* <p>The input is a plain text file with lines separated by newline characters.
*
* <p>Usage: <code>WordCount --input &lt;path&gt; --output &lt;path&gt;</code><br>
* If no parameters are provided, the program is run with default data from
* {@link WordCountData}.
*
* <p>This example shows how to:
* <ul>
* <li>write a simple Flink Streaming program,
* <li>use tuple data types,
* <li>write and use user-defined functions.
* </ul>
*/
public class WordCount {
// *************************************************************************
// PROGRAM
// *************************************************************************
public static void main(String[] args) throws Exception {
// Checking input parameters
final ParameterTool params = ParameterTool.fromArgs(args);
// set up the execution environment
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// make parameters available in the web interface
env.getConfig().setGlobalJobParameters(params);
// get input data
DataStream<String> text;
if (params.has("input")) {
// read the text file from given input path
text = env.readTextFile(params.get("input"));
} else {
System.out.println("Executing WordCount example with default input data set.");
System.out.println("Use --input to specify file input.");
// get default test text data
text = env.fromElements(WordCountData.WORDS);
}
DataStream<Tuple2<String, Integer>> counts =
// split up the lines in pairs (2-tuples) containing: (word,1)
text.flatMap(new Tokenizer())
// group by the tuple field "0" and sum up tuple field "1"
.keyBy(0).sum(1);
// emit result
if (params.has("output")) {
counts.writeAsText(params.get("output"));
} else {
System.out.println("Printing result to stdout. Use --output to specify output path.");
counts.print();
}
// execute program
env.execute("Streaming WordCount");
}
// *************************************************************************
// USER FUNCTIONS
// *************************************************************************
/**
* Implements the string tokenizer that splits sentences into words as a
* user-defined FlatMapFunction. The function takes a line (String) and
* splits it into multiple pairs in the form of "(word,1)" ({@code Tuple2<String,
* Integer>}).
*/
public static final class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>> {
@Override
public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
// normalize and split the line
String[] tokens = value.toLowerCase().split("\\W+");
// emit the pairs
for (String token : tokens) {
if (token.length() > 0) {
out.collect(new Tuple2<>(token, 1));
}
}
}
}
}
\ No newline at end of file
package org.hongxi.whatsmars.flink.streaming.util;
/**
* Provides the default data sets used for the WordCount example program.
* The default data sets are used, if no parameters are given to the program.
*
*/
public class WordCountData {
public static final String[] WORDS = new String[] {
"To be, or not to be,--that is the question:--",
"Whether 'tis nobler in the mind to suffer",
"The slings and arrows of outrageous fortune",
"Or to take arms against a sea of troubles,",
"And by opposing end them?--To die,--to sleep,--",
"No more; and by a sleep to say we end",
"The heartache, and the thousand natural shocks",
"That flesh is heir to,--'tis a consummation",
"Devoutly to be wish'd. To die,--to sleep;--",
"To sleep! perchance to dream:--ay, there's the rub;",
"For in that sleep of death what dreams may come,",
"When we have shuffled off this mortal coil,",
"Must give us pause: there's the respect",
"That makes calamity of so long life;",
"For who would bear the whips and scorns of time,",
"The oppressor's wrong, the proud man's contumely,",
"The pangs of despis'd love, the law's delay,",
"The insolence of office, and the spurns",
"That patient merit of the unworthy takes,",
"When he himself might his quietus make",
"With a bare bodkin? who would these fardels bear,",
"To grunt and sweat under a weary life,",
"But that the dread of something after death,--",
"The undiscover'd country, from whose bourn",
"No traveller returns,--puzzles the will,",
"And makes us rather bear those ills we have",
"Than fly to others that we know not of?",
"Thus conscience does make cowards of us all;",
"And thus the native hue of resolution",
"Is sicklied o'er with the pale cast of thought;",
"And enterprises of great pith and moment,",
"With this regard, their currents turn awry,",
"And lose the name of action.--Soft you now!",
"The fair Ophelia!--Nymph, in thy orisons",
"Be all my sins remember'd."
};
}
\ No newline at end of file
log4j.rootLogger=INFO, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p %-60c %x - %m%n
\ No newline at end of file
......@@ -29,6 +29,7 @@
<module>whatsmars-boot-sample-async</module>
<module>whatsmars-boot-sample-datasource</module>
<module>whatsmars-boot-sample-thymeleaf</module>
<module>whatsmars-boot-sample-swagger</module>
</modules>
<dependencies>
......
localhost:8080/swagger-ui/index.html
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>whatsmars-spring-boot-samples</artifactId>
<groupId>org.hongxi</groupId>
<version>Rocket.S8</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>whatsmars-boot-sample-swagger</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package org.hongxi.whatsmars.spring.boot;
package org.hongxi.whatsmars.boot.sample.swagger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@EnableAsync
@EnableScheduling
/**
* Created by shenhongxi on 2020/8/16.
*/
@SpringBootApplication
public class App {
public class Application {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
SpringApplication.run(Application.class, args);
}
}
\ No newline at end of file
}
package org.hongxi.whatsmars.spring.boot.common;
package org.hongxi.whatsmars.boot.sample.swagger.common;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
......
package org.hongxi.whatsmars.spring.boot.config;
package org.hongxi.whatsmars.boot.sample.swagger.config;
import com.fasterxml.classmate.TypeResolver;
import org.hongxi.whatsmars.spring.boot.App;
import org.hongxi.whatsmars.spring.boot.common.ProfileUtils;
import org.hongxi.whatsmars.boot.sample.swagger.Application;
import org.hongxi.whatsmars.boot.sample.swagger.common.ProfileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
......@@ -14,20 +13,18 @@ import org.springframework.web.context.request.async.DeferredResult;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.schema.WildcardType;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import static springfox.documentation.schema.AlternateTypeRules.newRule;
@Profile({"dev", "test"})
@ConditionalOnClass(EnableSwagger2.class)
@EnableSwagger2
@EnableOpenApi
@Configuration
public class SwaggerConfiguration {
public class SwaggerAutoConfiguration {
@Autowired
private TypeResolver typeResolver;
......@@ -35,50 +32,35 @@ public class SwaggerConfiguration {
private Environment env;
@Bean
public Docket swaggerSpringMvcPlugin() {
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("business-api")
.groupName("mars-api")
.select()
.apis(RequestHandlerSelectors.basePackage(App.class.getPackage().getName()))
.apis(RequestHandlerSelectors.basePackage(Application.class.getPackage().getName()))
.paths(PathSelectors.any())
.build()
.pathMapping("/")
.genericModelSubstitutes(ResponseEntity.class)
.alternateTypeRules(newRule(typeResolver.resolve(DeferredResult.class, typeResolver.resolve(ResponseEntity.class, WildcardType.class)), typeResolver.resolve(WildcardType.class)))
// .enableUrlTemplating(true)
.useDefaultResponseMessages(true)
.forCodeGeneration(false)
.host(host())
.apiInfo(apiInfo());
}
@Bean
public UiConfiguration uiConfig() {
return new UiConfiguration(
"validatorUrl",// url
"none", // docExpansion => none | list
"alpha", // apiSorter => alpha
"schema", // defaultModelRendering => schema
UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS,
false, // enableJsonEditor => true | false
true); // showRequestHeaders => true | false
}
private String host() {
String port = env.getProperty("server.port");
String port = env.getProperty("server.port", "8080");
if (ProfileUtils.isDev()) {
return "localhost:" + port;
}
return "test.toutiao.im";
return "test.hongxi.org";
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Toutiao API")
.description("用于调试Toutiao RestAPI,只在test/dev中放开,prod中关闭")
.title("Mars API")
.description("用于调试 Mars RestAPI,只在test/dev中放开,prod中关闭")
.version("0.1")
.build();
}
}
\ No newline at end of file
package org.hongxi.whatsmars.boot.sample.swagger.controller;
import io.swagger.annotations.Api;
import org.hongxi.whatsmars.boot.sample.swagger.model.User;
import org.springframework.web.bind.annotation.*;
/**
* Created by shenhongxi on 2020/8/16.
*/
@Api(tags = "Sample")
@RestController
@RequestMapping("/sample")
public class SampleController {
@GetMapping("/hello")
public String hello(@RequestParam String name) {
return "Hello, " + name;
}
@PostMapping("/register")
public User register(@RequestBody User user) {
System.out.println(user);
return user;
}
}
package org.hongxi.whatsmars.boot.sample.swagger.model;
import lombok.Data;
/**
* Created by shenhongxi on 2020/8/16.
*/
@Data
public class User {
private String name;
private Integer age;
}
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
\ No newline at end of file
date-format: yyyy-MM-dd HH:mm:ss
server:
port: 8080
tomcat:
uri-encoding: UTF-8
basedir: /data/logs/whatsmars-spring-boot
accesslog:
directory: logs
enabled: true
pattern: common
prefix: access_log
suffix: .log
\ No newline at end of file
# Spring Boot
👻 [start.spring.io](https://start.spring.io)
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss.
Most Spring Boot applications need very little Spring configuration.
启动后访问 localhost:8081/ <br />
swagger localhost:8081/swagger-ui.html
[《SpringBoot揭秘》](http://e.jd.com/30229176.html) `e.jd.com`
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.hongxi</groupId>
<artifactId>whatsmars-parent</artifactId>
<version>Rocket.S8</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>whatsmars-spring-boot</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>Spring Boot 实战</description>
<dependencies>
<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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- Swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!-- google -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.hongxi</groupId>
<artifactId>whatsmars-common</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package org.hongxi.whatsmars.spring.boot.async;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
* Created by shenhongxi on 2018/5/8.
*/
@Service
public class MessageService {
@Async
public CompletableFuture<String> send(String message) {
System.out.println(message);
return CompletableFuture.completedFuture(message);
}
}
package org.hongxi.whatsmars.spring.boot.common;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Locale;
/**
* Created by shenhongxi on 2017/6/28.
*/
@Component
public class LocaleService {
public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
@Autowired
private MessageSource messageSource;
public String getMessage(String key) {
Locale locale = LocaleContextHolder.getLocale();
return messageSource.getMessage(key, null, locale);
}
public static boolean isUSLocale() {
return LocaleContextHolder.getLocale().equals(Locale.US);
}
public static Locale resetLocale(Locale locale) {
Locale origin = LocaleContextHolder.getLocale();
LocaleContextHolder.setLocale(locale);
return origin;
}
}
package org.hongxi.whatsmars.spring.boot.common;
import org.hongxi.whatsmars.spring.boot.common.pojo.ReturnItem;
import org.hongxi.whatsmars.spring.boot.common.pojo.ReturnItems;
import org.hongxi.whatsmars.spring.boot.common.pojo.ReturnMessage;
import java.util.List;
/**
* Created by shenhongxi on 2017/11/27.
*/
public abstract class ReturnItemUtils {
public static ReturnItem newSuccessReturnItem() {
return newReturnItem(true);
}
public static <T> ReturnItems newSuccessReturnItems(List<T> messages, Long total) {
ReturnItems<T> items = new ReturnItems();
items.setItems(messages);
items.setTotal(total);
items.setStatus(200);
return items;
}
public static <T> ReturnItem newSuccessReturnItem(T message) {
return newReturnItem(true, message);
}
public static ReturnItem newErrorReturnItem() {
return newReturnItem(false);
}
public static ReturnItem newReturnItem(Boolean isSuccess) {
return newReturnItem(isSuccess, null);
}
public static <T> ReturnItem<T> newReturnItem(Boolean isSuccess, T message) {
if (Boolean.TRUE.equals(isSuccess)) {
return new ReturnItem(200, returnItemMsg(message, ReturnMessage.Message.OPERATION_SUCCESS.getValue()));
} else {
return new ReturnItem(400, returnItemMsg(message, ReturnMessage.Message.OPERATION_SUCCESS.getValue()));
}
}
private static Object returnItemMsg(Object message, String defaultMsg) {
return null == message ? defaultMsg : message;
}
}
package org.hongxi.whatsmars.spring.boot.common.pojo;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class ReturnItem<T> {
/* 请求状态 */
private int status;
/* 查询结果 */
private T item;
@JsonIgnore
private String[] ignoreFields = new String[]{};
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
public String[] getIgnoreFields() {
return ignoreFields;
}
public void setIgnoreFields(String[] ignoreFields) {
this.ignoreFields = ignoreFields;
}
public ReturnItem() {
super();
}
public ReturnItem(int status, T item) {
super();
this.status = status;
this.item = item;
}
public ReturnItem(int status, T item, String[] ignoreFields) {
this.status = status;
this.item = item;
this.ignoreFields = ignoreFields;
}
}
package org.hongxi.whatsmars.spring.boot.common.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
import java.util.List;
public class ReturnItems<T> {
/**
* 请求状态
*/
private int status;
/**
* 总条数
*/
private Long total;
/**
* 查询结果集
*/
private List<T> items;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
private Date serverDateTime = new Date();
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public long getTotal() {
if(total == null){
return items != null ? items.size() : 0;
}
return total;
}
public void setTotal(long total) {
this.total = total;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
public Date getServerDateTime() {
return serverDateTime;
}
public void setServerDateTime(Date serverDateTime) {
this.serverDateTime = serverDateTime;
}
public ReturnItems() {
super();
}
public ReturnItems(int status, long total, List<T> items) {
super();
this.status = status;
this.total = total;
this.items = items;
}
public ReturnItems(List<T> items) {
super();
this.items = items;
}
}
package org.hongxi.whatsmars.spring.boot.common.pojo;
public class ReturnMessage {
private int status = 200;
private String message = "操作成功";
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ReturnMessage() {
super();
}
public ReturnMessage(int status) {
super();
this.status = status;
}
public ReturnMessage(int status, String message) {
super();
this.status = status;
this.message = message;
}
public enum Message{
/**
* 操作成功
*/
OPERATION_SUCCESS("操作成功"),
/**
* 操作失败
*/
OPERATION_ERROR("操作失败"),
/**
* 操作异常
*/
OPERATION_ABNORMAL("操作异常"),
/**
* 更新异常
*/
UPDATE_ANOMALIES("更新异常"),
/**
* 参数错误
*/
PARAMETER_ERROR("参数错误"),
/**
* 非法请求
*/
ILLEGAL_REQUEST("非法请求"),
/**
* 登陆超时
*/
LOGIN_TIMEOUT("登陆超时"),
/**
* 未登录
*/
NOT_LOGGED_IN("未登录"),
/**
* 登陆失败
*/
FAIL_LOGIN("登陆失败"),
/**
* 存在
*/
EXIST("存在"),
/**
* 不存在
*/
NOT_EXIST("不存在");
String value;
public String getValue() {
return value;
}
private Message(String value) {
this.value = value;
}
}
}
package org.hongxi.whatsmars.spring.boot.config;
import org.hongxi.whatsmars.spring.boot.interceptor.ApiAuthInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.servlet.DispatcherType;
/**
* Created by javahongxi on 2017/11/16.
*/
@Configuration
@EnableConfigurationProperties(UserConfig.class)
public class AppConfiguration {
@ConditionalOnProperty(value = "api.auth.enabled")
@Profile({"dev", "prod"})
@Configuration
public static class WebMvcConf extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(apiAuthInterceptor())
.addPathPatterns("/api/mars/**")
.addPathPatterns("/do")
.pathMatcher(new AntPathMatcher());
}
@Bean
public HandlerInterceptor apiAuthInterceptor() {
return new ApiAuthInterceptor();
}
@Bean
public FilterRegistrationBean commonsRequestLoggingFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setName("requestLoggingFilter");
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new CommonsRequestLoggingFilter());
registration.addUrlPatterns("/**");
registration.setOrder(Integer.MAX_VALUE);
return registration;
}
}
}
package org.hongxi.whatsmars.spring.boot.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* Created by shenhongxi on 2017/6/20.
*/
@ConfigurationProperties(prefix="user")
public class UserConfig {
private String welcome;
private List<String> noFilterUrl;
public String getWelcome() {
return welcome;
}
public void setWelcome(String welcome) {
this.welcome = welcome;
}
public List<String> getNoFilterUrl() {
return noFilterUrl;
}
public void setNoFilterUrl(List<String> noFilterUrl) {
this.noFilterUrl = noFilterUrl;
}
}
package org.hongxi.whatsmars.spring.boot.controller;
import org.hongxi.whatsmars.spring.boot.async.MessageService;
import org.hongxi.whatsmars.spring.boot.dao.UserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* Created by shenhongxi on 2017/6/29.
*/
@Component
@Order(value = 1)
public class InitRunner implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UserMapper userMapper;
@Autowired
private MessageService messageService;
@Override
public void run(String... args) throws Exception {
logger.info("init......createIfNotExistsTable");
userMapper.createIfNotExistsTable();
for (int i = 0; i < 10; i++) {
logger.info("send result: {}", messageService.send("message" + i).get());
}
}
}
package org.hongxi.whatsmars.spring.boot.controller;
import org.hongxi.whatsmars.spring.boot.config.UserConfig;
import org.hongxi.whatsmars.spring.boot.common.LocaleService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;
/**
* Created by shenhongxi on 2017/3/27.
*/
@Api(tags = "Sample", description = "样例")
@Controller
public class SampleController {
@Autowired
private UserConfig userConfig;
@Autowired
private LocaleService localeService;
/**
* 设置区域解析器 (default is AcceptHeaderLocaleResolver)
*/
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setCookieName("language");
localeResolver.setCookieMaxAge(Integer.MAX_VALUE);
localeResolver.setDefaultLocale(LocaleService.DEFAULT_LOCALE); // Locale.getDefault()
return localeResolver;
}
@RequestMapping(value = "/changeLang", method = RequestMethod.POST)
@ResponseBody
public String changeLang(HttpServletRequest request, HttpServletResponse response, @RequestParam String lang){
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if ("zh".equals(lang)) {
localeResolver.setLocale(request, response, Locale.SIMPLIFIED_CHINESE);
} else if("en".equals(lang)){
localeResolver.setLocale(request, response, Locale.US);
}
return "lang:" + LocaleContextHolder.getLocale().getLanguage();
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Map<String,Object> map) {
System.out.println(LocaleService.isUSLocale());
map.put("hello", "Hi, boy!");
map.put("country", localeService.getMessage("country"));
return "index";
}
@Profile("test,dev")
@RequestMapping(value = "/welcome", method = RequestMethod.GET)
@ResponseBody
public String welcome() {
return userConfig.getWelcome();
}
}
package org.hongxi.whatsmars.spring.boot.controller;
import com.github.pagehelper.Page;
import org.hongxi.whatsmars.common.result.Result;
import org.hongxi.whatsmars.common.result.ResultHelper;
import org.hongxi.whatsmars.spring.boot.common.ReturnItemUtils;
import org.hongxi.whatsmars.spring.boot.common.pojo.ReturnItems;
import org.hongxi.whatsmars.spring.boot.exception.AppException;
import org.hongxi.whatsmars.spring.boot.model.User;
import org.hongxi.whatsmars.spring.boot.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* Created by shenhongxi on 2017/11/16.
* @see org.hongxi.whatsmars.spring.boot.exception.AppExceptionHandler
*/
@RestController
@RequestMapping("/user")
public class UserController {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UserService userService;
@GetMapping("/find/{username}")
public Result<User> find(@PathVariable("username") String username) {
User user = userService.findByUsername(username);
return ResultHelper.newSuccessResult(user);
}
@PostMapping("/add")
public Result add(@RequestParam(name = "name") String username,
@RequestParam(required = false) String nickname,
@RequestParam(required = false, defaultValue = "1") Integer gender,
@RequestParam Integer age) {
User user = new User();
user.setUsername(username);
user.setNickname(nickname);
user.setGender(gender);
user.setAge(age);
userService.add(user);
return ResultHelper.newSuccessResult();
}
@PutMapping("/update")
public Result update(@RequestBody User user) { // 以json格式接收参数, RequestBody也可省略
userService.update(user);
return ResultHelper.newSuccessResult();
}
@DeleteMapping("/delete")
public Result delete(@RequestParam Long id) {
userService.delete(id);
return ResultHelper.newSuccessResult();
}
@RequestMapping(value = "/e", method = RequestMethod.GET)
public HttpStatus e(@RequestParam(required = false) String error) {
if (error != null) throw AppException.build(error);
return HttpStatus.OK;
}
@GetMapping("/query")
public ReturnItems<User> query(@RequestParam(value = "offset", defaultValue = "0") Integer offset,
@RequestParam(value = "limit", defaultValue = "30") Integer limit) {
Page<User> page = userService.query(offset, limit);
return ReturnItemUtils.newSuccessReturnItems(page.getResult(), page.getTotal());
}
@GetMapping("/findByNicknameAndGender")
public ReturnItems<User> findByNicknameAndGender(@RequestParam String nickname,
@RequestParam Integer gender) {
ReturnItems<User> returnItems = new ReturnItems<>();
List<User> users = userService.findByNicknameAndGender(nickname, gender);
long total = users == null ? 0 : users.size();
return ReturnItemUtils.newSuccessReturnItems(users, total);
}
@PostMapping("/addBatch")
public Result addBatch() {
try {
userService.testTransaction(buildUsers());
} catch (Exception e) {
logger.error("#########user addBatch error", e);
return ResultHelper.newErrorResult();
}
return ResultHelper.newSuccessResult();
}
private List<User> buildUsers() {
List<User> users = new ArrayList<>();
Date now = new Date();
long t = now.getTime();
User user = new User();
user.setUsername("tb" + t++);
user.setNickname("hongxi");
user.setGender(1);
user.setAge(28);
user.setCreateDate(now);
user.setUpdateDate(now);
users.add(user);
user = new User();
user.setUsername("tb" + t++);
user.setNickname("lilei");
user.setGender(1);
user.setAge(27);
user.setCreateDate(now);
user.setUpdateDate(now);
users.add(user);
return users;
}
}
package org.hongxi.whatsmars.spring.boot.converter;
import org.hongxi.whatsmars.common.util.DateUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Date;
import java.util.regex.Pattern;
/**
* Created by zhaozhong on 2016/9/6.
*/
@Component
public class StringToDateConverter implements Converter<String, Date> {
private Pattern dateTimePattern = Pattern.compile(DateUtils.DATETIME_FORMAT_REGEX);
private Pattern shortDatePattern = Pattern.compile(DateUtils.SHORTDATE_FORMAT_REGEX);
private Pattern shortDate2Pattern = Pattern.compile(DateUtils.SHORTDATE_FORMAT2_REGEX);
private Pattern datePattern = Pattern.compile(DateUtils.DATE_FORMAT_REGEX);
private Pattern date2Pattern = Pattern.compile(DateUtils.DATE_FORMAT2_REGEX);
@Override
public Date convert(String source) {
if (!StringUtils.isEmpty(source)) {
if(shortDatePattern.matcher(source).matches()) {
return DateUtils.getDateFormat(source, DateUtils.DATE_SHORT_FORMAT);
}else if(datePattern.matcher(source).matches()) {
return DateUtils.getDateFormat(source, DateUtils.DATEFORMAT);
}else if(dateTimePattern.matcher(source).matches()) {
return DateUtils.getDateFormat(source, DateUtils.DATETIMEFORMAT);
}else if(shortDate2Pattern.matcher(source).matches()) {
return DateUtils.getDateFormat(source, DateUtils.DATE_SHORT_FORMAT2);
}else if(date2Pattern.matcher(source).matches()) {
return DateUtils.getDateFormat(source, DateUtils.DATEFORMAT2);
}
}
return null;
}
}
package org.hongxi.whatsmars.spring.boot.dao;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.hongxi.whatsmars.spring.boot.model.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* Created by shenhongxi on 2017/6/26.
*/
@Mapper
public interface UserMapper {
void createIfNotExistsTable();
@Select("select * from user where username = #{username}")
User findByUsername(String username);
void insert(User user);
void insertBatch(List<User> users);
List<User> query();
void update(User user);
void delete(Long id);
List<User> findByNicknameAndGender(@Param("nickname") String nickname, @Param("gender") Integer gender);
}
package org.hongxi.whatsmars.spring.boot.exception;
import org.hongxi.whatsmars.common.result.Result;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
/**
* Created by shenhongxi on 2017/11/16.
*/
public class AppException extends RuntimeException {
private Code errorCode;
private String errorMsg;
private AppException() {
}
@Override
public String getMessage() {
if (super.getMessage() != null) return super.getMessage();
return this.getErrorMsg();
}
public static AppException build(Code errorCode, String errorMsg) {
return new AppException().setErrorCode(errorCode).setErrorMsg(errorMsg);
}
public static AppException build(String errorMsg) {
return new AppException().setErrorCode(Code.ERROR).setErrorMsg(errorMsg);
}
public static AppException build(BindingResult bindingResult) {
StringBuilder sb = new StringBuilder();
for (ObjectError e : bindingResult.getAllErrors()) {
sb.append(e.getDefaultMessage()).append(";");
}
return new AppException().setErrorCode(Code.ERROR).setErrorMsg(sb.toString());
}
public Code getErrorCode() {
return errorCode;
}
public AppException setErrorCode(Code errorCode) {
this.errorCode = errorCode;
return this;
}
public String getErrorMsg() {
return errorMsg;
}
public AppException setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
return this;
}
public Result toResult() {
return new Result(getErrorCode().value, getErrorMsg());
}
public enum Code {
SUCCESS(200),
ERROR(500);
private int value;
Code(int code) {
this.value = code;
}
public int getValue() {
return value;
}
}
}
package org.hongxi.whatsmars.spring.boot.exception;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import org.hongxi.whatsmars.common.result.Result;
import org.hongxi.whatsmars.spring.boot.common.ProfileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.logging.LogLevel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 异常信息拦截
* Created by shenhongxi on 2017/11/16.
*/
@ControllerAdvice(annotations = { RestController.class, Controller.class})
public class AppExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* 业务异常处理,直接返回异常信息提示
*/
@ExceptionHandler(AppException.class)
public ResponseEntity<Result> businessExceptionHandle(AppException exception, HttpServletRequest request) {
logError(exception, request, LogLevel.WARN);
return new ResponseEntity<Result>(exception.toResult(), HttpStatus.OK);
}
/**
* 其他为定义异常,统一返回默认错误信息,避免打印出异常堆栈
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<Result> defaultExceptionHandle(Exception exception, HttpServletRequest request) {
logError(exception, request, LogLevel.ERROR);
return new ResponseEntity<Result>(new Result(AppException.Code.ERROR.getValue(), ProfileUtils.isDev() ? exception.getMessage() : "操作失败"), HttpStatus.OK);
}
public void logError(Exception ex, HttpServletRequest request, LogLevel logLevel) {
Map<String, String> map = Maps.newHashMap();
map.put("message", ex.getMessage());
map.put("from", request.getRemoteAddr());
final String queryString = request.getQueryString();
map.put("path", queryString != null ? (request.getRequestURI() + "?" + queryString) : request.getRequestURI());
switch (logLevel) {
case ERROR:
logger.error(JSON.toJSONString(map), ex);
break;
case WARN:
logger.warn(JSON.toJSONString(map));
break;
}
}
}
package org.hongxi.whatsmars.spring.boot.filter;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by shenhongxi on 2017/11/15.
*/
@Order(1)
@Component
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("================Filter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if (!(servletRequest instanceof HttpServletRequest) || !(servletResponse instanceof HttpServletResponse)) {
throw new ServletException(
"OncePerRequestFilter just supports HTTP requests");
}
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
System.out.println("================ServletContext: " + req.getServletContext());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
package org.hongxi.whatsmars.spring.boot.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by javahongxi on 2017/11/16.
*/
public class ApiAuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("================preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
package org.hongxi.whatsmars.spring.boot.job;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* Created by shenhongxi on 2017/6/30.
*/
@Component
public class DemoJob {
@Scheduled(cron = "0 * * * * ?")
public void execute() {
System.out.println(System.currentTimeMillis());
}
}
package org.hongxi.whatsmars.spring.boot.listener;
import org.springframework.stereotype.Component;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* Created by shenhongxi on 2017/11/15.
*/
@Component
public class ServContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("================Hello, Server....");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
package org.hongxi.whatsmars.spring.boot.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.Date;
/**
* Created by shenhongxi on 2017/6/26.
*/
public class User implements Serializable {
private static final long serialVersionUID = 6469790070035101683L;
@JsonProperty("user_id") // 有时候前端定义的字段名与后端不一致时采用此法处理
private Long id;
private String username;
private String nickname;
private Integer gender;
private Integer age;
private Date createDate;
private Date updateDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
}
package org.hongxi.whatsmars.spring.boot.service;
import com.github.pagehelper.Page;
import org.hongxi.whatsmars.spring.boot.model.User;
import java.util.List;
/**
* Created by shenhongxi on 2017/6/26.
*/
public interface UserService {
User findByUsername(String username);
void add(User user);
void update(User user);
void delete(Long id);
Page<User> query(int offset, int limit);
void addBatch(List<User> users);
void add(List<User> users);
List<User> findByNicknameAndGender(String nickname, Integer gender);
void testTransaction(List<User> users);
}
package org.hongxi.whatsmars.spring.boot.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.hongxi.whatsmars.spring.boot.dao.UserMapper;
import org.hongxi.whatsmars.spring.boot.model.User;
import org.hongxi.whatsmars.spring.boot.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Created by shenhongxi on 2017/6/21.
*/
@Service("userService")
public class UserServiceImpl implements UserService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UserMapper userMapper;
@Override
public User findByUsername(String username) {
return userMapper.findByUsername(username);
}
@Override
public void add(User user) {
userMapper.insert(user);
logger.info("add user success, username: {}", user.getUsername());
}
@Override
public void update(User user) {
userMapper.update(user);
}
@Override
public void delete(Long id) {
userMapper.delete(id);
}
@Override
public Page<User> query(int offset, int limit) {
return PageHelper.offsetPage(offset, limit).doSelectPage(() -> userMapper.query());
}
@Override
public void addBatch(List<User> users) {
userMapper.insertBatch(users);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(List<User> users) {
int i = 0;
for (User user : users) {
// if (i++ == 1) throw new RuntimeException("TEST TX");
userMapper.insert(user);
}
}
@Override
public List<User> findByNicknameAndGender(String nickname, Integer gender) {
return userMapper.findByNicknameAndGender(nickname, gender);
}
@Override
public void testTransaction(List<User> users) {
// 同一个类中调有事务的方法,无事务,因为事务的本质是调代理
add(users);
}
}
spring:
profiles:
active: dev
thymeleaf:
cache: false
messages:
basename: i18n/messages
jackson:
date-format: yyyy-MM-dd HH:mm:ss
mybatis:
config-location: classpath:mybatis-config.xml
endpoints:
shutdown:
enabled: true
path: /danger
sensitive: true
management:
port: 9900
address: 127.0.0.1
context-path: /manage
security:
role: SUPERUSER
security:
user:
name: admin
password: secret
api:
auth:
enabled: true
user:
welcome: Hello, World!
noFilterUrl: /,/login
logging.level.tk.mybatis.pagehelper.mapper: WARN
pagehelper:
closeConn: true
offset-as-page-num: false
autoDialect: true
---
spring:
profiles: dev
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://db.hongxi.org:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: n36bxXMnHina
connectionTimeout: 30000
idleTimeout: 60000
maxLifetime: 1800000
minimumIdle: 5
maximumPoolSize: 10
connection-test-query: SELECT 1
redis:
host: 127.0.0.1
port: 6379
timeout: 10000
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 0
server:
port: 8081
tomcat:
uri-encoding: UTF-8
basedir: /data/logs/whatsmars-spring-boot
accesslog:
directory: logs
enabled: true
pattern: common
prefix: access_log
suffix: .log
---
spring:
profiles: test
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://db.hongxi.org:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: n36bxXMnHina
connectionTimeout: 30000
idleTimeout: 60000
maxLifetime: 1800000
minimumIdle: 5
maximumPoolSize: 10
connection-test-query: SELECT 1
redis:
host: 127.0.0.1
port: 6379
timeout: 10000
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 0
server:
port: 8081
tomcat:
uri-encoding: UTF-8
basedir: /data/logs/whatsmars-spring-boot
accesslog:
directory: logs
enabled: true
pattern: common
prefix: access_log
suffix: .log
---
spring:
profiles: prod
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://db.hongxi.org:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: n36bxXMnHina
connectionTimeout: 30000
idleTimeout: 60000
maxLifetime: 1800000
minimumIdle: 5
maximumPoolSize: 10
connection-test-query: SELECT 1
redis:
host: 127.0.0.1
port: 6379
timeout: 10000
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 0
server:
port: 8081
tomcat:
uri-encoding: UTF-8
basedir: /data/logs/whatsmars-spring-boot
accesslog:
directory: logs
enabled: true
pattern: common
prefix: access_log
suffix: .log
\ No newline at end of file
spring:
application:
name: whatsmars-sb
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="debug">
<properties>
<property name="log.path">/data/logs/whatsmars-spring-boot</property>
</properties>
<appenders>
<console name="Console" target="SYSTEM_OUT">
<Filters>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT"
onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:stack:SSS}] [%p] [%t] - [%X{sid}] %c{1.} - %m%n"/>
</console>
<RollingFile name="RollingFileDebug" fileName="${log.path}/debug.log"
filePattern="${log.path}/$${date:yyyy-MM-dd}/debug-%d{yyyy-MM-dd}-%i.log">
<Filters>
<ThresholdFilter level="INFO" onMatch="DENY"
onMismatch="ACCEPT"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT"
onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:stack:SSS}] [%p] [%t] - [%X{sid}] %c{1.} - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileInfo" fileName="${log.path}/info.log"
filePattern="${log.path}/$${date:yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log">
<Filters>
<ThresholdFilter level="INFO"/>
<ThresholdFilter level="WARN" onMatch="DENY"
onMismatch="NEUTRAL"/>
</Filters>
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:stack:SSS}] [%p] [%t] - [%X{sid}] %c{1.} - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${log.path}/warn.log"
filePattern="${log.path}/$${date:yyyy-MM-dd}/warn-%d{yyyy-MM-dd}-%i.log">
<Filters>
<ThresholdFilter level="WARN"/>
<ThresholdFilter level="ERROR" onMatch="DENY"
onMismatch="NEUTRAL"/>
</Filters>
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:stack:SSS}] [%p] [%t] - [%X{sid}] %c{1.} - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${log.path}/error.log"
filePattern="${log.path}/$${date:yyyy-MM-dd}/error-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="ERROR"/>
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:stack:SSS}] [%p] [%t] - [%X{sid}] %c{1.} - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileTrace" fileName="${log.path}/trace.log"
filePattern="${log.path}/$${date:yyyy-MM-dd}/trace-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:stack:SSS}] [%p] [%t] - [%X{sid}] %c{1.} - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<File name="UserService" fileName="${log.path}/user-service.log">
<PatternLayout pattern="%d{HH:mm:stack.SSS} [%t] %-5level %logger{36} - %msg%n" />
</File>
</appenders>
<loggers>
<root level="INFO">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
<appender-ref ref="RollingFileDebug"/>
<appender-ref ref="RollingFileTrace"/>
</root>
<logger name="com.whatsmars.spring.boot.service.impl.UserServiceImpl" level="info" additivity="false">
<appender-ref ref="UserService"/>
</logger>
<!-- mybatis loggers -->
<logger name="com.ibatis" level="INFO"/>
<logger name="org.apache.ibatis" level="INFO"/>
<logger name="org.mybatis.spring" level="INFO"/>
<logger name="com.ibatis.common.jdbc.SimpleDataSource" level="INFO"/>
<logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"/>
<logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="DEBUG"/>
<!-- sql loggers -->
<logger name="java.sql.Connection" level="DEBUG" additivity="true"/>
<logger name="java.sql.Statement" level="DEBUG" additivity="true"/>
<logger name="java.sql.PreparedStatement" level="DEBUG" additivity="true"/>
<logger name="java.sql.ResultSet" level="DEBUG" additivity="true"/>
<!-- spring loggers -->
<logger name="org.springframework" level="WARN"/>
<logger name="org.springframework.web" level="WARN"/>
<logger name="springfox.documentation" level="WARN"/>
<logger name="org.hibernate" level="ERROR"/>
<logger name="springfox.documentation" level="ERROR"/>
</loggers>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.hongxi.whatsmars.spring.boot.dao.UserMapper">
<update id="createIfNotExistsTable">
CREATE TABLE IF NOT EXISTS user (id BIGINT AUTO_INCREMENT, username VARCHAR(20) NOT NULL, nickname VARCHAR(20), gender TINYINT, age INT, create_date DATETIME, update_date DATETIME, PRIMARY KEY (id));
</update>
<!--<select id="findByUsername" parameterType="string" resultType="User">
select * from user where username = #username#
</select>-->
<insert id="insert" parameterType="User">
insert into user(username, nickname, gender, age, create_date, update_date)
values(#{username}, #{nickname}, #{gender}, #{age}, NOW(), NOW())
</insert>
<insert id="insertBatch" parameterType="list">
insert into user(username, nickname, gender, age, create_date, update_date) values
<foreach collection="list" item="item" separator=",">
(#{item.username}, #{item.nickname}, #{item.gender}, #{item.age}, #{item.createDate}, #{item.updateDate})
</foreach>
</insert>
<select id="query" resultType="User">
select * from user
</select>
<update id="update" parameterType="User">
update user set update_date = NOW
<if test="username != null">, username = #{username}</if>
<if test="nickname != null">, nickname = #{nickname}</if>
<if test="age != null">, age = #{age}</if>
where id = #{id}
</update>
<delete id="delete">
delete from user where id = #{id}
</delete>
<select id="findByNicknameAndGender" resultType="User">
select * from user where nickname = #{nickname} and gender = #{gender}
</select>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright ${license.git.copyrightYears} the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J2"/>
<setting name="callSettersOnNulls" value="true"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<typeAlias type="org.hongxi.whatsmars.spring.boot.model.User" alias="User" />
</typeAliases>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>thymeleaf</title>
</head>
<body>
<h1 th:inline="text">thymeleaf</h1>
<p th:text="${hello}"></p>
<p th:text="${country}"></p>
<p th:text="#{country}"></p>
</body>
</html>
\ No newline at end of file
package org.hongxi.whatsmars.spring.boot.dao;
import org.hongxi.whatsmars.spring.boot.model.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Created by shenhongxi on 2018/2/1.
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("dev")
public class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void insert() {
assert userMapper != null;
userMapper.createIfNotExistsTable();
User user = new User();
user.setUsername("javahongxi");
user.setNickname("hongxi");
user.setGender(1);
user.setAge(28);
userMapper.insert(user);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册