.properties 文件的輪嗎問題
Spring.http.encoding.enabled=true
@EnableScheduling //@EnableScheduling註解開啟對計劃任務的支持
@MapperScan("org.fMes.mesApi.mapper") //把mapper包下的所有接口類,編譯之後都會變成實現類
@Autowired //自動搜索所有的bean 以request匹配
@Override //子類重寫父類方法
@Target({ElementType.METHOD, ElementType.TYPE}) //註解作用目標 ElementType.METHOD(作用方法)ElementType.TYPE(接口,類,枚舉,註解)等等
@Retention(RetentionPolicy.RUNTIME) //可以用來修飾註解,是註解的註解 RetentionPolicy.RUNTIME註解被保存在class文件中,但jvm加載class文件後,仍存在
//@interface 是註解類,用來聲明一個註解,其中每一個方法實際上是聲明了一個配置參數。
@Component //表明一個類會作為組件類,並告知Spring要為這個類創建bean
@PropertySource:指定自定義配置文件的位置和名稱
@Configuration:自定義配置類,Spring容器組件 指定當前類為配置類,也可以使用@Component代替
@EnableConfigurationProperties(Myproperties.class)
開啟配置類的屬性注入功能
@ImportResource:指定xml文件配置 用於config文件下的
@Bean(name = "myService") //將標註方法的返回值存到Spring容器中
@PropertySource:引入 了读取properties文件的注解 @PropertySource
例:
获取配置文件中的值通过Environment 具体使用方法
@Autowired
private Environment env;
env.getProperty("userName")
//還有
@Value("${jco.lang}")
private String lang
@RestController
@RestController = @Controller + @ResponseBody组成,等号右边两位同志简单介绍两句,就明白我们@RestController的意义了:
@Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。当然也有语义化的作用,即代表该类是充当Controller的作用
@ResponseBody 它的作用简短截说就是指该类中所有的API接口返回的数据,甭管你对应的方法返回Map或是其他Object,它会以Json字符串的形式返回给客户端,本人尝试了一下,如果返回的是String类型,则仍然是String。
備註:
如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,配置的视图解析器InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。
例如:本来应该到success.jsp页面的,则其显示success.
2)如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
3)如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。
@ Swagger2
是一款目前世界最流行的API管理工具。但目前Swagger已经形成一个生态圈,能够管理API的整个生命周期,从设计、文档到测试与部署。
Swagger2是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful 风格的Web 服务,用於解決API接口問題
@EnableSwagger2 開啟Swagger
@Configuration
@EnableSwagger2
public class Swagger2Configuration {
//api接口包扫描路径
public static final String SWAGGER_SCAN_BASE_PACKAGE = "com.xxx";
public static final String VERSION = "1.0.0";
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
.paths(PathSelectors.any()) // 可以根据url路径设置哪些请求加入文档,忽略哪些请求
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("xxx服务") //设置文档的标题
.description("xxx API 接口文档") // 设置文档的描述
.version(VERSION) // 设置文档的版本信息-> 1.0.0 Version information
.termsOfServiceUrl("http://www.xxx.com") // 设置文档的License信息->1.3 License information
.build();
}
}
@Service
@Service注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中
@Target({ElementType.METHOD, ElementType.TYPE}) //註解作用目標 ElementType.METHOD(作用方法)ElementType.TYPE(接口,類,枚舉,註解)等等
@Retention(RetentionPolicy.RUNTIME) //可以用來修飾註解,是註解的註解 RetentionPolicy.RUNTIME註解被保存在class文件中,但jvm加載class文件後,仍存在
public @interface AuthToken {}
//@interface 是註解類,用來聲明一個註解,其中每一個方法實際上是聲明了一個配置參數。
@EnableTransactionManagement
首先使用注解 @EnableTransactionManagement 开启事务支持后
@EnableScheduling //@EnableScheduling註解開啟對計劃任務的支持
@JSONType(naming = PropertyNamingStrategy.PascalCase, serialzeFeatures = { SerializerFeature.UseSingleQuotes })
在类上通过@JSONType定制序列化:
//配置序列化的时候,不序列化id sex
@JSONField(ordinal =0)
这个注解的作用是序列化字段的顺序,默认是0
@JSONField(name = “”)
当前端传过来的字段名不一样的时候,我们可以在字段名上加上这个注解
@JSONField(format = “”)
当前端传过JSON时间字符串的想转成Date,或者想指定转成JSON字符串日期的格式时,就可以用到这个注解
@JSONField(serialize = 布尔类型)
是否要把这个字段序列化成JSON字符串,默认是true
Springboot攔截器之Handlerinterceptor:
最常用的登錄攔截、權限效驗、防重複提交
HandlerInterceptor 接口
preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView ;
afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
instanceof:二元運算符:判斷一個引用類型變量所指向的對象是否是一個類的實例 返回值是boolean類型
//兩個例子
if(!(handler instanceof HandlerMethod)){
return true;
}
if(s instanceof String){
System.out.println(“true”)
}
攔截器HandlerInterceptor中的preHandle方法
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从http请求头中取出token
final String token = request.getHeader(JwtUtil.AUTH_HEADER_KEY);
//如果不是映射到方法,直接通过
if(!(handler instanceof HandlerMethod)){
return true;
}
//如果是方法探测,直接通过
if (HttpMethod.OPTIONS.equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return true;
}
//如果方法有JwtIgnore注解,直接通过 //放行逻辑
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method=handlerMethod.getMethod();
if (method.isAnnotationPresent(JwtIgnore.class)) {
JwtIgnore jwtIgnore = method.getAnnotation(JwtIgnore.class);
if(jwtIgnore.value()){
return true;
}
}
// LocalAssert.isStringEmpty(token, "token为空,鉴权失败!");
if (StringUtils.isEmpty(token)){
throw new BaseException("token为空,鉴权失败!");
}
//验证,并获取token内部信息
Claims claims = JwtUtil.parseJWT(token);
String userToken = claims.getSubject();
//将token放入本地缓存
WebContextUtil.setUserToken(userToken);
return true;
}
//如果不是映射到方法,直接通过
if(!(handler instanceof HandlerMethod)){
return true;
}
-----------------------------------------------------------------------------------------------------------------
ApplicationContextAware
实现接口ApplicationContextAware这种获取方式适用于大多数项目内业务接口不方便注入的时候的调用
当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。换句话说,就是这个类可以直接获取spring配置文件中,所有有引用到的bean对象。
【备注】
(1)在spring的配置文件中,注册方法类AppUtil。之所以方法类AppUtil能够灵活自如地获取ApplicationContext,就是因为spring能够为我们自动地执行了setApplicationContext。但是,spring不会无缘无故地为某个类执行它的方法的,所以,就很有必要通过注册方法类AppUtil的方式告知spring有这样子一个类的存在。这里我们使用@Component来进行注册,或者我们也可以像下面这样在配置文件声明bean:
<bean id="appUtil" class="com.htsoft.core.util.AppUtil"/>
(2)加载Spring配置文件时,如果Spring配置文件中所定义的Bean类实现了ApplicationContextAware 接口,那么在加载Spring配置文件时,会自动调用ApplicationContextAware 接口中的
public void setApplicationContext(ApplicationContext context) throws BeansException
方法,获得ApplicationContext对象,ApplicationContext对象是由spring注入的。前提必须在Spring配置文件中指定该类。
(3)使用静态的成员ApplicationContext类型的对象。
使用场景备注
从ApplicationContextAware获取ApplicationContext上下文的情况,仅仅适用于当前运行的代码和已启动的Spring代码处于同一个Spring上下文,否则获取到的ApplicationContext是空的。
比如我要为当前系统加入一个定时任务,定时刷新Memcache缓存。这个定时任务框架是公司的框架,下面是我的ApplicationContextAware 接口实现类:
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;//声明一个静态变量保存
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext正在初始化,application:"+appContext);
this.applicationContext=applicationContext;
}
public static <T> T getBean(Class<T> clazz){
if(applicationContext==null){
System.out.println("applicationContext是空的");
}else{
System.out.println("applicationContext不是空的");
}
return applicationContext.getBean(clazz);
}
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
}
定时任务类如下,定时任务初始化的时候,首先会调用作业类的public static Object getObject()方法返回作业类的实例。
@Component
public class RemoteCacheJob extends AbstractSaturnJavaJob {
@Autowired
private AdsRemoteCacheJob adsRemoteCacheJob;
@Autowired
private ILogService logService;
// 实例化的过程:系统会首先调用作业类的public static Object getObject()方法,
// 如果返回为null,则调用作业类的无参构造方法来实例化;否则直接使用getObject()方法返回的对象作为作业类实例。
public static Object getObject() {
return ApplicationContextUtil.getBean(RemoteCacheJob .class);
}
@Override
public void handleJavaJob(String jobName, Integer shardItem, String shardParam, SaturnJobExecutionContext shardingContext)
throws InterruptedException {
System.out.println("处理定时任务");
}
}
-----------------------------------------------------------------------------------------------------------------
TypeHandler概念
MyBatis 中的 TypeHandler 类型处理器用于 JavaType 与 JdbcType 之间的转换,用于 PreparedStatement 设置参数值和从 ResultSet 或 CallableStatement 中取出一个值。MyBatis 内置了大部分基本类型的类型处理器,所以对于基本类型可以直接处理,当我们需要处理其他类型的时候就需要自定义类型处理器
1.1 :可以实现TypeHandler<T>接口
public class EmptyStringIfNull implements TypeHandler<String> {
@Override
public String getResult(ResultSet rs, String columnName) throws SQLException {
return (rs.getString(columnName) == null) ? "" : rs.getString(columnName);
}
@Override
public String getResult(ResultSet rs, int columnIndex) throws SQLException {
return (rs.getString(columnIndex) == null) ? "" : rs.getString(columnIndex);
}
@Override
public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
return (cs.getString(columnIndex) == null) ? "" : cs.getString(columnIndex);
}
@Override
public void setParameter(PreparedStatement ps, int arg1, String str, JdbcType jdbcType) throws SQLException {
}
}
1.2 可以继承 BaseTypeHandler<T>
-----------------------------------------------------------------------------------------------------------------
FilterRegistrationBean過濾器
有2种方式可以实现过滤器
1:通过FilterRegistrationBean实例注册
2:通过@WebFilter注解生效
这里选择第一种,因为第二种不能设置过滤器之间的优先级.
@Configuration
public class EncodingFilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setForceEncoding(true);
characterEncodingFilter.setEncoding("UTF-8");
registrationBean.setFilter(characterEncodingFilter);
return registrationBean;
}
}
-----------------------------------------------------------------------------------------------------------------
CharacterEncodingFilter
是spring内置过滤器的一种,用来指定请求或者响应的编码格式。在web开发中经常被从来使用
@Configuration
public class EncodingFilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setForceEncoding(true);
characterEncodingFilter.setEncoding("UTF-8");
registrationBean.setFilter(characterEncodingFilter);
return registrationBean;
}
}
-----------------------------------------------------------------------------------------------------------------
前後數據交互的時候大多數是json來傳輸數據的。
也可用@RequestBody和@ResponseBody接收和發送數據
也可以用FastJsonHttpMessageConverter
Json轉換器
fastjson转换器的两个功能:
1、自动给json请求添加请求头:Content-Type:application/json。
2、参数下划线转驼峰。
public class FMesHttpMsgConverter extends FastJsonHttpMessageConverter {
@Override
protected void writeInternal(Object object, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
if(object instanceof String) {
Charset charset = this.getCharset();
StreamUtils.copy((String)object, charset, outputMessage.getBody());
}else {
super.writeInternal(object, outputMessage);
}
}
}
其他方式
//依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
SpringBoot启动类中配置转换器
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
//1、创建FastJson信息转换对象
FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
//2、创建FastJsonConfig对象并设定序列化规则 序列化规则详见SerializerFeature类中,后面会讲
FastJsonConfig fastJsonConfig= new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,SerializerFeature.WriteNonStringKeyAsString);
//本人就坑在WriteNonStringKeyAsString 将不是String类型的key转换成String类型,否则前台无法将Json字符串转换成Json对象
//3、中文乱码解决方案
List<MediaType> fastMedisTypes = new ArrayList<MediaType>();
fastMedisTypes.add(MediaType.APPLICATION_JSON_UTF8);//设定Json格式且编码为utf-8
fastConverter.setSupportedMediaTypes(fastMedisTypes);
//4、将转换规则应用于转换对象
fastConverter.setFastJsonConfig(fastJsonConfig);
return new HttpMessageConverters(fastConverter);
}
Controller
当访问controller的时候,就会将对象转化成Json字符串返回了
//初始化入库情况选项数据
@ApiOperation("初始化入库情况选项数据")
@RequestMapping(value = "init-stock-statu",method = RequestMethod.POST)
@ResponseBody
@CrossOrigin
public ResultBean<?> initStockStatus(){
Map<String, Map<Object, String>> partThree = new HashMap<>(3);
//入库状态 下拉选框
Map<Object, String> stockStatus = new HashMap<>(6);
for (StockStatusEnum c : StockStatusEnum.values()) {
stockStatus.put(c.getCode(), c.getDesc());
}
partThree.put("stockStatus", stockStatus);
//入库类型 下拉选框
Map<Object, String> stockType = new HashMap<>(6);
for (StockTypeEnum c : StockTypeEnum.values()) {
stockType.put(c.getCode(), c.getDesc());
}
partThree.put("stockType", stockType);
return new ResultBean<>(partThree);
}
WebMvcConfigurer
WebMvcConfigurer是什么?我们简单理解就是以前我们以前用xml配置时候的,spring-web.xml。就是我们可以配置很多web方面的组件,比如说消息转化,拦截器,视图转化器,跨域配置,资源控制器等等。
1.WebMvcConfigurer就是我们来配置web请求过程中的一些组建。
常用的方法:
/* 拦截器配置 */
void addInterceptors(InterceptorRegistry var1);
/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);
/**
*静态资源处理
**/
void addResourceHandlers(ResourceHandlerRegistry registry);
/* 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/**
* 这里配置视图解析器
**/
void configureViewResolvers(ViewResolverRegistry registry);
/* 配置内容裁决的一些选项*/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;
configureMessageConverters://信息转换器
例如:
@Configuration
public class FMesWebMvcConf implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// TODO Auto-generated method stub
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/img/**").addResourceLocations("classpath:/static/img/");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
WebMvcConfigurer.super.addViewControllers(registry);
}
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
return factory -> {
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/index.html");
factory.addErrorPages(error404Page);
};
}
}
隨機值設置以及參數間引用
語法格式
${random.xx} xx表示需要指定生成的隨機數類型和範圍
示例代碼
my.secret=${random.value}
my.number=${random.int}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
Springboot 整合Mybatis
使用註解方式整合MyBatis
步驟: 創建Mapper 接口文件:@Mapper
編寫測試方法進行接口方法測試機整合測試
使用配置文件配置方式整合MyBatis
步驟
創建Mapper 接口文件:@Mapper
創建XML映射文件:編寫對應的SQL語句
在全局文件中配置xml映射文件路徑以及實體類別名映射路徑
編寫測試方法進行接口方法測試及整合測試
Springboot 整合JPA
Spring Data JPA基本介紹
1. 編寫ORM實體類:實體類與數據表進行映射,並且配置好映射關係。
2. 編寫Repository接口:針對不同的表數據操作編寫各自對應的Repository接口,並根據需要編寫對應的數據操作方法。
pom.xml文件下放置mapper.xml文件,該mapper.xml文件是在resources下
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
pom.xml文件下放置mapper.xml文件,該mapper.xml文件是在Java下
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/java</directory>
<excludes>
<exclude>**/*.xml</exclude>
</excludes>
</resource>
</resources>
自動生成代碼插件:在pom.xml里
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
在springboot的配置文件的一些常用的配置,在application.properties文件裡
server.port=8084
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:8080/nokia
spring.datasource.username=root
spring.datasource.password=root
#druid數據源 的屬性默認參數設置進行了修改
#數據類型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#最大連接數
spring.datasource.maxActive=20
#初始化連接數據
spring.datasource.initialSize=1
#spring.datasource.maxWait=60000
#最小空閒數
spring.datasource.minIdle=1
#開啟駝峰命名匹配映射
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.call-setters-on-nulls=true
mybatis-plus.mapper-locations=classpath:com.example.demo.mapper.mapping/*.xml
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.mvc.throw-exception-if-no-handler-found=true
spring.web.resource.add-mappings=false
#mybatis配置xml文件路径
mybatis.mapper-locations=classpath:mapper/*.xml
#對應實體類路徑
mybatis.type-aliases-package=com.demo.entity