快速使用spring-boot来构建web应用
java基础及mvn创建应用
重要概念
- 什么是注解:带有@符号的就是注解,注解起一个解释标识作用,程序会根据反射来找对应的函数
- 什么是javaBean对象:在spring框架中,带有javaBean注解的类将被自动实例化,无序用户在new操作,对于单例模式时非常友好的
- 程序如何执行的:在spring中,程序的执行会根据注解反射对象进行实例化,也就是程序会不断根据注解来自动化实例对象
第一步:创建项目
$ mvn archetype:generate
...
Choose archetype:
1: internal -> org.apache.maven.archetypes:maven-archetype-archetype (An archetype which contains a sample archetype.)
...
6: internal -> org.apache.maven.archetypes:maven-archetype-profiles ()
7: internal -> org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains a sample Maven project.)
...
10: internal -> org.apache.maven.archetypes:maven-archetype-webapp (An archetype which contains a sample Maven Webapp project.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 7:
Define value for property 'groupId': com.xxx
Define value for property 'artifactId': lijc
Define value for property 'version' 1.0-SNAPSHOT: :
Define value for property 'package' com.xxx: :
$ tree
.
├── pom.xml
├── readme.md
└── src
├── main
│ └── java
│ └── com
│ └── xxx
│ └── App.java
└── test
└── java
└── com
└── xxx
└── AppTest.java
第二步:安装依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.10</version>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
第三步:构建业务代码
添加配置文件
- 在src/main/resources/application.yml
server:
port: 8090
compression:
enabled: true
min-response-size: 1024
mime-types: application/json
info:
version: 1.2
定义返回响应体
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
class ResultResponse {
@Override
public String toString() {
return "{" +
" version='" + getVersion() + "'" +
", code='" + getCode() + "'" +
", msg='" + getMsg() + "'" +
", data='" + getData() + "'" +
"}";
}
@Value("${info.version}")
private String version;
private Integer code;
private String msg;
private Object data;
public String getVersion() {
return this.version;
}
public void setVersion(String version) {
this.version = version;
}
public Integer getCode() {
return this.code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return this.data;
}
public void setData(Object data) {
this.data = data;
}
public ResultResponse() {
}
}
配置swagger接口文档
@Configuration
@EnableSwagger2
class SwaggerConfig {
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("API接口文档")
.description("使用swagger来测试接口文档")
.version("1.0.0")
.build();
}
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.xxxx"))
.paths(PathSelectors.any())
.build();
}
}
定义一个业务接口
@RestController
@Api(value = "Hello接口")
class Hello2 {
@Autowired
private ResultResponse rresp;
@RequestMapping(method = RequestMethod.POST, value = "/hello2/{id}")
@ApiOperation(value = "测试post请求", notes = "测试post请求")
public ResultResponse hello2(
@RequestParam(defaultValue = "jack", name = "name") String name,
@RequestPart("file") MultipartFile file,
@PathVariable(value = "id") Integer id,
@RequestParam(name = "age") Integer age) {
Map<String, Object> m = new HashMap<String, Object>();
m.put("age", age);
m.put("id", id);
rresp.setCode(200);
rresp.setMsg("成功");
rresp.setData(m);
System.out.println(rresp);
return rresp;
}
}
针对实际业务设计拦截器
@Component
class MyInterceptor implements HandlerInterceptor {
@Autowired
private ResultResponse rresp;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("你的请求被拦截,需要审核是否放行");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
response.setStatus(403);
rresp.setCode(403);
rresp.setMsg("被拦截");
rresp.setData("");
JSONObject resp = (JSONObject) JSONObject.toJSON(rresp);
response.getWriter().println(resp.toJSONString());
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex)
throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
构建主函数
@Configuration
@SpringBootApplication
@ComponentScan("com.xxxx")
@EnableAutoConfiguration
public class App implements WebMvcConfigurer {
@Autowired
private MyInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns(
"/hello2/**",
"/swagger-ui/**",
"/v2/api-docs",
"/swagger-resources/**",
"/css/**",
"/js/**");
}
public static void main(String[] args) {
// System.out.println("Hello World!");
SpringApplication.run(App.class, args); // 自动去扫描注解为RequestMapping的接口
}
}
运行
$ mvn spring-boot:run
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.10)
2022-03-15 14:26:56.849 INFO 3344 --- [ restartedMain] com.xxxx.App : Starting App using Java 17.0.2 on rockontroldeMacBook-Pro.local with PID 3344 (/Users/rockontrol/Desktop/js_code/test/java-test/springboot-test-ljc/target/classes started by rockontrol in /Users/rockontrol/Desktop/js_code/test/java-test/springboot-test-ljc)
2022-03-15 14:26:56.850 INFO 3344 --- [ restartedMain] com.xxxx.App : No active profile set, falling back to 1 default profile: "default"
2022-03-15 14:26:57.040 INFO 3344 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http)
2022-03-15 14:26:57.043 INFO 3344 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-03-15 14:26:57.044 INFO 3344 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.58]
2022-03-15 14:26:57.054 INFO 3344 --- [ restartedMain] o.a.c.c.C.[Tomcat-1].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-03-15 14:26:57.055 INFO 3344 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 200 ms
2022-03-15 14:26:57.129 INFO 3344 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2022-03-15 14:26:57.137 INFO 3344 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path ''
2022-03-15 14:26:57.140 INFO 3344 --- [ restartedMain] com.xxxx.App : Started App in 5.34 seconds (JVM running for 5056.503)
2022-03-15 14:26:57.143 INFO 3344 --- [ restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged
效果
- 访问地址:http://127.0.0.1:8090/swagger-ui/index.html
完整代码如下
package com.xxxx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.web.bind.annotation.PathVariable;
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.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import org.springframework.stereotype.Component;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
class ResultResponse {
@Override
public String toString() {
return "{" +
" version='" + getVersion() + "'" +
", code='" + getCode() + "'" +
", msg='" + getMsg() + "'" +
", data='" + getData() + "'" +
"}";
}
@Value("${info.version}")
private String version;
private Integer code;
private String msg;
private Object data;
public String getVersion() {
return this.version;
}
public void setVersion(String version) {
this.version = version;
}
public Integer getCode() {
return this.code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return this.data;
}
public void setData(Object data) {
this.data = data;
}
public ResultResponse() {
}
}
@Configuration
@EnableSwagger2
class SwaggerConfig {
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("API接口文档")
.description("使用swagger来测试接口文档")
.version("1.0.0")
.build();
}
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.xxxx"))
.paths(PathSelectors.any())
.build();
}
}
@RestController
@Api(value = "Hello接口")
class Hello2 {
@Autowired
private ResultResponse rresp;
@RequestMapping(method = RequestMethod.POST, value = "/hello2/{id}")
@ApiOperation(value = "测试post请求", notes = "测试post请求")
public ResultResponse hello2(
@RequestParam(defaultValue = "jack", name = "name") String name,
@RequestPart("file") MultipartFile file,
@PathVariable(value = "id") Integer id,
@RequestParam(name = "age") Integer age) {
Map<String, Object> m = new HashMap<String, Object>();
m.put("age", age);
m.put("id", id);
rresp.setCode(200);
rresp.setMsg("成功");
rresp.setData(m);
System.out.println(rresp);
return rresp;
}
}
@Component
class MyInterceptor implements HandlerInterceptor {
@Autowired
private ResultResponse rresp;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("你的请求被拦截,需要审核是否放行");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
response.setStatus(403);
rresp.setCode(403);
rresp.setMsg("被拦截");
rresp.setData("");
JSONObject resp = (JSONObject) JSONObject.toJSON(rresp);
response.getWriter().println(resp.toJSONString());
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex)
throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
@Configuration
@SpringBootApplication
@ComponentScan("com.xxxx")
@EnableAutoConfiguration
public class App implements WebMvcConfigurer {
@Autowired
private MyInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns(
"/hello2/**",
"/swagger-ui/**",
"/v2/api-docs",
"/swagger-resources/**",
"/css/**",
"/js/**");
}
public static void main(String[] args) {
// System.out.println("Hello World!");
SpringApplication.run(App.class, args); // 自动去扫描注解为RequestMapping的接口
}
}