参考资料
后续的学习需要使用到java和springboot,因此提前学习下相关知识
ssm框架简单示例的配置过程,https://download.csdn.net/download/sinat_41567654/87588187
spring项目约定
创建springboot项目的依赖
org.springframework.boot spring-boot-starter-parent 2.5.0 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-configuration-processor true
创建配置文件application.yml
server:port: 8090
创建入口类
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class,args);}
}
创建controller
@Controller
@RequestMapping("/main")
public class HelloController { @RequestMapping("/hello")@ResponseBodypublic String hello(){System.out.println("hello world");return "hello world";}
}
启动server,访问端口8090
curl 127.0.0.1:8090/main/hello
StatusCode: 200
入口类注解的含义
# SpringApplication
- SpringBootApplication: 全局入口类 有且只能有一个
- mian 函数参数可以在启动时指定jvm参数覆盖默认配置
# @SpringBootApplication 注解等价于:
- @SpringBootConfiguration 标识这是一个springboot的配置类,默认自定配置Spring环境
- @EnableAutoConfiguration 自动与项目中集成的第三方技术进行集成
- @orgponentScan 扫描入口类所在子包以及子包后代包中注解
在springboot中可以通过注解创建对象
@orgponent
通用的对象创建注解
@Controller
用来创建控制器对象@Service
用来创建业务层对象@Repository
用来创建DAO层对象 @Configuration
代表这是一个spring的配置类相当于Spring.xml配置文件
@Bean
用来在工厂中创建这个@Bean注解标识的对象
@Configuration
用来在工厂中一次性创建多个对象,而@orgponent
用来创建单个对象
@Configuration
public class Beans {@Beanpublic Calendar calendar(){return Calendar.getInstance();}
}
属性注入,在application.yml配置文件中指定需要注入的值
@ConfigurationProperties(prefix="前缀")
,必须提供set方法@RestController
// @ConfigurationProperties(prefix = "user")
public class HelloController {//基本类型+String类型+日期类型@Value("${name}")private String name;@Value("${age}")private Integer age;@Value("${sex}")private Boolean sex;@Value("${price}")private Double price;@Value("${bir}")private Date bir;//注入数组@Value("${qqs}")private String[] qqs;//注入list@Value("${lists}")private List lists;//注入maps@Value("#{${maps}}")private Map maps;...
}
默认推荐thymeleaf,可以跳过
引入依赖
jstl jstl 1.2
org.apache.tomcat.embed tomcat-embed-jasper
引入插件
springboot_day1 org.springframework.boot spring-boot-maven-plugin
配置视图解析器
spring:mvc:view:prefix: / # /代表访问项目中webapp中页面suffix: .jsp
修改jsp配置无需重启server
server:servlet:jsp:init-parameters:development: true
在本地安装mariadb或者直接使用rds托管数据库
引入依赖
org.alibaba druid 1.2.4
mysql mysql-connector-java 5.1.38
org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.4
配置配置文件
spring:mvc:view:prefix: /suffix: .jspdatasource:type: org.apache.orgmons.dbcp.BasicDataSource #指定连接池类型driver-class-name: org.mysql.jdbc.Driver #指定驱动url: jdbc:mysql://localhost:3306/learndb?characterEncoding=UTF-8 #指定urlusername: root #指定用户名password: zhaojiew #指定密码
加入mybatis配置
mybatis:mapper-locations: classpath:org/example/mapper/*.xml #指定mapper配置文件位置type-aliases-package: org.example.entity #指定起别名所在包
@SpringBootApplication
@MapperScan("org.example.dao")
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class,args);}
}
建表
https://www.yiibai.org/sql/sql-sample-database.html
https://github.org/q343509740/Store/blob/master/classicmodels.sql
CREATE TABLE `t_clazz` (`id` varchar(40) NOT NULL,`name` varchar(80) DEFAULT NULL,`no` varchar(90) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
编写实体类
public class Clazz {private String id;private String name;private String no;//get set 方法省略....
}
DAO接口以及Mapper
public interface ClazzDAO {List findAll();
}
开发Service以及实现
//接口
public interface ClazzService {List findAll();
}
//实现
@Service
@Transactional
public class ClazzServiceImpl implements ClazzService {@Autowiredprivate ClazzDAO clazzDAO;@Transactional(propagation = Propagation.SUPPORTS)@Overridepublic List findAll() {return clazzDAO.findAll();}
}
开发Controller
@RestController
public class ClazzController {@Autowiredprivate ClazzService clazzService;//查询所有@RequestMapping("findAll")public List findAll(){return clazzService.findAll();}
}
启动项目访问测试
curl http://localhost:8989/example/findAll
引入依赖
org.springframework.boot spring-boot-starter-test test
编写测试类
@SpringBootTest
public class TestEmpService {@Autowiredprivate EmpService empService;@Testpublic void test(){empService.findAll().forEach(emp-> System.out.println(emp));}
}
避免重启使修改生效,在项目中开启了springboot
全局热部署之后只需要在修改之后等待几秒即可使修改生效
项目中引入依赖
org.springframework.boot spring-boot-devtools true
设置idea中支持自动编译
# 1.开启自动编译
Preferences | Build, Execution, Deployment | orgpiler -> 勾选上 Build project automatically 这个选项
# 2.开启允许在运行过程中修改文件
ctrl + alt + shift + / ---->选择1.Registry ---> 勾选 orgpiler.automake.allow.when.app.running 这个选项
启动项目检测热部署是否生效
# 1.启动出现如下restartedMain日志代表生效
2019-07-17 21:23:17.566 INFO 4496 --- [ restartedMain] org.example.InitApplication : Starting InitApplication on chenyannandeMacBook-Pro.local with PID 4496 (/Users/chenyannan/IdeaProjects/ideacode/springboot_day1/target/classes
springboot框架 集成了日志 logback 日志
项目日志分类
rootLogger(根全局日志) ,用来监听项目中所有的运行日志 包括引入依赖jar中的日志
logger(指定包级别日志),用来监听项目中指定包中的日志信息
配置日志
注意:SpringBoot框架中默认根日志为INFO
logging:level:root: debug #指定根日志级别(一般不推荐修改根日志,输出信息太多,推荐使用子日志)org.example.dao: debug #指定某个包中日志file:name: example.log #指定日志名称path: ./ #指定日志文件目录
项目中使用日志
@Controller
public class HelloController {//声明日志成员private static final Logger log = LoggerFactory.getLogger(HelloController.class);@RequestMapping("/hello")@ResponseBodypublic String hello(){System.out.println("======hello world=======");logger.debug("DEBUG,{}","信息");logger.info("INFO,{}","信息");logger.warn("WARN,{}","信息");logger.error("ERROR,{}","信息");return "hello";}
}
对于spring
具体配置
1.类 implement xxAdvice接口
2.XML进行配置
springboot只提供了注解支持
引入依赖
org.springframework.boot spring-boot-starter-aop
aop相关注解
前置切面
@Aspect
@Configuration
public class MyAspect {@Before("execution(* org.example.service.*.*(..))")public void before(JoinPoint joinPoint){System.out.println("前置通知");joinPoint.getTarget();//目标对象joinPoint.getSignature();//方法签名joinPoint.getArgs();//方法参数}
}
后置切面
@Aspect
@Configuration
public class MyAspect {@After("execution(* org.example.service.*.*(..))")public void before(JoinPoint joinPoint){System.out.println("后置通知");joinPoint.getTarget();//目标对象joinPoint.getSignature();//方法签名joinPoint.getArgs();//方法参数}
}
注意: 前置通知和后置通知都没有返回值,方法参数都为joinpoint
环绕切面
@Aspect
@Configuration
public class MyAspect {@Around("execution(* org.example.service.*.*(..))")public Object before(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("进入环绕通知");proceedingJoinPoint.getTarget();//目标对象proceedingJoinPoint.getSignature();//方法签名proceedingJoinPoint.getArgs();//方法参数Object proceed = proceedingJoinPoint.proceed();//放行执行目标方法System.out.println("目标方法执行之后回到环绕通知");return proceed;//返回目标方法返回值}
}
注意: 环绕通知存在返回值,参数为ProceedingJoinPoint,如果执行放行,不会执行目标方法,一旦放行必须将目标方法的返回值返回,否则调用者无法接受返回数据
准备上传页面
编写控制器
@Controller
@RequestMapping("/file")
public class FileController {@RequestMapping("/upload")public String upload(MultipartFile deomfile, HttpServletRequest request) throws IOException {String realPath = request.getRealPath("/upload");deomfile.transferTo(new File(realPath,deomfile.getOriginalFilename()));//文件上传return "index";}
}
修改文件上传大小
#上传时出现如下异常: 上传文件的大小超出默认配置 默认10M
nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (38443713) exceeds the configured maximum (10485760)
#修改上传文件大小:
spring:http:multipart:max-request-size: 209715200 #用来控制文件上传大小的限制max-file-size: 209715200 #用来指定服务端最大文件大小 spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB
文件下载提供下载文件链接
corejava.txt
开发控制器
@RequestMapping("/download")
public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {String realPath = request.getRealPath("/upload");FileInputStream is = new FileInputStream(new File(realPath, fileName));ServletOutputStream os = response.getOutputStream();response.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));IOUtils.copy(is,os);IOUtils.closeQuietly(is);IOUtils.closeQuietly(os);}
开发拦截器
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {System.out.println("======1=====");return true;//返回true 放行 返回false阻止}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {System.out.println("=====2=====");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {System.out.println("=====3=====");}
}
配置拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()) //拦截器.addPathPatterns("/**") //拦截路径.excludePathPatterns("/file/**") //排除路径.order(1); //优先级}
}
注意:order用来执行多个拦截器的执行顺序,order书写是自然数,按照自然数顺序执行
CORS,跨域资源共享(Cross-origin resource sharing),允许浏览器向跨源服务器,发出XMLHttpRequest(ajax)请求,从而克服了AJAX只能同源使用的限制。
同源策略
[same origin policy]是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。
源
[origin]就是协议、域名和端口号。例如:http://www.baidu.com:80这个URL。
同源,若地址里面的协议、域名和端口号均相同
则属于同源。
不受同源限制的操作
页面中的链接,重定向以及表单提交是不会受到同源策略限制的;
跨域资源的引入,如嵌入到页面中的,
,,
等。
受到同源限制的操作
出现错误:Access-Control-Allow-Origin
使用CORS解决同源限制
@CrossOrigin
注解
@RestController
@RequestMapping("/demos")
@CrossOrigin
public class DemoController {@GetMappingpublic String demos() {System.out.println("demo");return "demo ok";}
}
全局解决跨域问题
@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用corsConfiguration.addAllowedHeader("*"); // 2允许任何头corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)source.registerCorsConfiguration("/**", corsConfiguration); //4处理所有请求的跨域配置return new CorsFilter(source);}
}
测试跨域的发送脚本
test cors
最后顺带看看gradle的内容
参考资料
Gradle 是一款Google 推出的基于 JVM、通用灵活的项目构建工具,支持 Maven,JCenter 多种第三方仓库;支持传递性依赖管理、废弃了繁杂的xml 文件,转而使用简洁的、支持多种语言的build 脚本文件。
虽然目前市面上常见的项目构建工具有Ant、Maven、Gradle,主流还是Maven
自动化构建工具 | Ant | Maven | Gradle |
---|---|---|---|
性能 | 最高 | 最低 | 居中 |
仓库 | 自管理 | maven仓库 | 多种远程仓库 |
依赖管理 | ivy | GAV坐标 | GAV坐标 |
插件支持 | 方便 | 较难 | 方便 |
特定目录结构 | 无 | 是 | 和maven一致 |
配置文件 | xml | xml | 脚本 |
侧重点 | 小型项目构建 | 项目包管理 | 大型项目构建 |
定位 | 使用较少 | 目前主流 | 未来趋势 |
Gradle官网:https://gradle.org/
Gradle官方下载安装教程页面:https://gradle.org/install/
Gradle官方用户手册:https://docs.gradle.org/current/userguide/userguide.html
springboot和gradle存在版本兼容性问题,Gradle 插件需要gradle6.8 版本及以。我的环境选择corretto java11和Gradle 8.0.2
配置好java和gradle的环境变量即可
gradle项目结构和maven一致,除了
常用命令
gradle clean
gradle classes //编译业务代码和匹配值文件
gradle test
gradle build
gradle build -x text //跳过测试构建
修改maven源
gradle的init.d目录为build前操作,在此处创建init.gradle
指定仓库位置
allprojects {repositories {mavenLocal()maven { name "Alibaba" ; url "https://maven.aliyun.com/repository/public" } maven { name "Bstek" ; url "https://nexus.bsdn.org/content/groups/public/" } mavenCentral()}buildscript {repositories {maven { name "Alibaba" ; url 'https://maven.aliyun.com/repository/public' } maven { name "Bstek" ; url 'https://nexus.bsdn.org/content/groups/public/' } maven { name "M2" ; url 'https://plugins.gradle.org/m2/' }}}
}
存放init.gradle
文件的位置,按从上往下顺序执行init脚本
gradle --init-script path/init.gradle
USER_HOME/.gradle/
USER_HOME/.gradle/init.d/
GRADLE_HOME/init.d/
对 Gradle 的一层包装,用于解决实际开发中可能会遇到的不同的项目需要不同版本的 Gradle**。本地可以不配置gradle**,使用 gradle 项目自带的wrapper
gradlew、gradlew.cmd的使用方式与gradle使用方式完全一致,常用指令
--gradle-vesion
,指定gradle版本--gradle-disribution-url
,指定下载gradle的url地址执行流程如下
gradlew build
,读取gradle-wrapper.properties
GRADLE_USER_HOME/wrapper/dists
中GRADLE_USER_HOME/caches
gradle-wrapper.properties
文件字段
配置mvnw,指定maven版本
mvn wrapper:wrapper -Dmaven=3.8.5
默认从.mvn
目录下获取配置文件
.mvn/wrapper/maven-wrapper.properties
,指定了下载wrapper和maven的版本distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
默认将maven下载到/home/ec2-user/.m2/wrapper/dists
下
$ tree .m2 -L 2
.m2
├── repository
│ ├── antlr
...
│ └── xpp3
├── settings.xml
└── wrapper└── dists
默认下载jar包仍旧为.m2/repository
目录