1.创建spring boot工程
1.1填写项目名Artifact,组织名,java版本。
1.2.勾选初始依赖。
- Web下勾选Spring Web (或者是Spring Web Start)
- Template Englines勾选Thymeleaf
- SQL勾选:MySQL Driver,JDBC API 和 MyBatis Framework三项
确定项目路径,点击finish即可。
等待IDEA右下角的processes running下载完毕即可。
创建好的初始目录结构如图:
1.3建立项目结构文件夹
- 在com.example.firstspringboot下新建controller文件夹(前端控制器)
- 在com.example.firstspringboot下新建service文件夹(也叫服务层,业务层),
- 在com.example.firstspringboot下新建bean文件夹(也叫model层,模型层,entity层,实体层,domain层),
- 在com.example.firstspringboot下新建dao文件夹(数据访问层,也叫repository),
- 在com.example.firstspringboot.service下新建impl文件夹(数据服务接口的实现(serviceImpl),
- 在com.example.firstspringboot 下新建utils文件夹(工具类),
- 在com.example.firstspringboot 下新建config文件夹(配置类)
建立好后的结构如图所示:
2.运行spring boot项目
2.1 返回字符串模式
上述创建的spring boot项目会自动创建好启动类文件,在com.example.firstspringboot目录下,类名 为你的项目名,内容如图:
添加@EnableAutoConfiguration 和 @ComponentScan 表示自动包扫描。
在controller文件夹下建一个的HelloController类;(Controller类要添加@Controller注解,项目启动时,SpringBoot会自动扫描加载Controller)
@Controller
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String hello(){
return "hello first spring boot web";
}
}
代码中@GetMapping("/hello")注解,已经默认封装了@RequestMapping(method = RequestMethod.GET)
@ResponseBody 将方法的返回值,以特定的格式写入到response的body区域,进而将数据返回给客户端。
当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象(此时必须在templates中定义相关view层html文件,否则会报错)。
当注解了ResponseBody如果返回值是字符串,那么直接将字符串写到客户端;如果是一个对象,会将对象转化为json串,然后写到客户端。
配置application.properties 文件,因为我们见创建项目时,勾选了mysql和mybatis,所以要配置数据库信息,但这里只是配置,并不是真正的使用,配置的值也是假的,只是为了不报错,配置信息如下:
#访问根路径
#访问端口号
server.port=8080
#编码格式
server.tomcat.uri-encoding=utf-8
#数据库相关配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sql_test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
#session生命周期
server.servlet.session.timeout=30m
到这里就可以启动springboot应用了,打开FirstspringbootApplication,点击run-FirstspringbootApplication,如下图代表启动成功。
访问Controller,此时就可以访问我们定义的HelloController了,不过此时访问返回的只是字符串,在浏览器中输入: http://localhost:8080/hello 如下图即代表成功。
2.2 返回html文件(thymeleaf模板)
参考https://www.cnblogs.com/wotoufahaiduo/p/11178629.html)。
因为在创建项目时,勾选了使用thymeleaf模板,项目已经默认导入了,因此直接使用即可。
在application.properties 中添加配置thymeleaf文件
#thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
在HelloController中添加方法,去掉ResponseBody注解,去掉后默认返回的是View视图,即以return 的值为名的html文件。
@GetMapping("/index")
public String hellohtml(ModelMap model) {
User user = new User();
user.setUsername("jack");
user.setPassword("112233");
user.setHobbies(Arrays.asList(new String[]{"singing", "dancing", "football"}));
Map<String, String> maps = new HashMap<>();
maps.put("1", "o");
maps.put("2", "g");
maps.put("3", "a");
maps.put("4", "j");
user.setSecrets(maps);
model.addAttribute("user", user);
return "/index";
}
添加辅助Bean实体。
import java.util.List;
import java.util.Map;
public class User {
String username;
String password;
List<String> hobbies;
Map<String, String> secrets;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getHobbies() {
return hobbies;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public Map<String, String> getSecrets() {
return secrets;
}
public void setSecrets(Map<String, String> secrets) {
this.secrets = secrets;
}
}
创建并编辑index.html
在templates下创建index.html文件
修改html文件如下:
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--字符串输出-->
<p th:text="'hello SpringBoot'">hello thymeleaf</p>
<!--数学运算-->
<p th:text="9 + 10"></p>
<p th:text="10 * 10"></p>
<p th:text="1 - 10"></p>
<p th:text="8 / 3"></p>
<p th:text="3 % 2"></p>
<!--操作域对象-->
<p th:text="${user}"></p>
<p th:text="${user.username}"></p>
<!--遍历数组-->
<table th:each="item, sta:${user.hobbies}">
<tr>
<td th:text="${item}"></td>
<td th:text="${sta.index}"></td>
<td th:text="${sta.odd}"></td>
<td th:text="${sta.size}"></td>
</tr>
</table>
<!--遍历map-->
<div th:each="item:${user.secrets}" th:text="${item.key}"></div>
<!--遍历数组-->
<div th:each="item:${user.hobbies}" th:text="${item}"></div>
<!--设置属性-->
<input type="text" th:attr="value=${user.username}">
<input type="text" th:attr="value=${user.username}, title=${user.username}">
<!--表单数据绑定-->
<form action="" th:object="${user}">
<input type="text" th:value="*{username}">
<input type="password" th:value="*{password}">
<select>
<option th:each="item:${user.secrets}" th:text="${item.value}" th:selected="'a' eq ${item.value}"></option>
</select>
</form>
<!--解析html文本内容-->
<p th:utext="'<span>html</span>'"></p>
<!--流程控制-->
<p th:if="${user.username} != ${user.password}">yes</p>
<div th:switch="${user.username}">
<p th:case="rose">name is rose</p>
<p th:case="jack">name is jack</p>
</div>
<!--外部引入-->
<link rel="stylesheet" th:href="@{/css/index.css}">
<script th:src="@{/js/index.js}"></script>
<a th:href="@{/home}">home</a>
</body>
</html>
在浏览器中输入:http://localhost:8080/index ,运行结果如下图所示:
2.3 返回 实体Bean的JSON 对象
在HelloController中添加如下代码,
注解 @ResponseBody,使用在控制层(controller)的方法上,作用:
- 将方法的返回值,以特定的格式写入到response的body区域,进而将数据返回给客户端。
- 当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。
- 如果返回值是字符串,那么直接将字符串写到客户端;如果是一个对象,会将对象转化为json串,然后写到客户端。
@GetMapping("/jsondata")
@ResponseBody
public User hellojson() {
User user = new User();
user.setUsername("jack");
user.setPassword(null);
user.setHobbies(Arrays.asList(new String[]{"singing", "dancing", "football"}));
Map<String, String> maps = new HashMap<>();
maps.put("1", "o");
maps.put("2", "g");
maps.put("3", "a");
maps.put("4", null);
user.setSecrets(maps);
return user;
}
在浏览器中输入:http://localhost:8080/jsondata ,结果如下图所示:
2.4 自定义Json 转换器(使用Fastjson)返回
spring boot会自动将实体Bean转为json对象,默认使用的是jackson-databind作为json数据的处理器,除了自带json转换器,也可以使用Gson,FastJson等自动以json转换器。本文以Fastjson为例:
1.去除依赖jackson-databind,引入fastjson依赖
2.需要开发者提供一个HttpMessageConverter即可。
添加修改pom.xml如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--除去jackson-databind依赖,使用fastjson-->
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<!--fastJson,需要实现MyFastjsonConfig -->
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
在config下添加FastjsonConfig类,重新build,下载pom中新引入的组件
@Configuration
public class FastjsonConfig {
@Bean
FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setCharset(Charset.forName("UTF-8"));
//还需要在application.properties添加:
//spring.http.encoding.force-response=true
config.setSerializerFeatures(
//json格式化
SerializerFeature.PrettyFormat,
SerializerFeature.WriteMapNullValue,//保留map空的字段。
SerializerFeature.WriteNullListAsEmpty,//List字段如果为null,输出为[],而非null
SerializerFeature.WriteNullStringAsEmpty,//字符类型字段如果为null,输出为"",而非null
SerializerFeature.DisableCircularReferenceDetect,//消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
SerializerFeature.WriteNullBooleanAsFalse //Boolean字段如果为null,输出为false,而非null
);
converter.setFastJsonConfig(config);
return converter;
}
}
修改hellojson函数,赋空值,和空数组查看效果。
@GetMapping("/jsondata")
@ResponseBody
public User hellojson() {
User user = new User();
user.setUsername("jack");
user.setPassword(null);
user.setHobbies(Arrays.asList(new String[]{}));
Map<String, String> maps = new HashMap<>();
maps.put("1", "o");
maps.put("2", "g");
maps.put("3", "a");
maps.put("4", "b");
user.setSecrets(maps);
return user;
}
打开浏览器,http://localhost:8080/jsondata ,结果如下图所示:
可以看到,null值和空数组都被转为"",和[]了。
2.4 List,Map, Json对象返回
2.4.1 Json对象直接返回
@GetMapping(value="/jsondata",produces="application/json;charset=UTF-8")
@ResponseBody
public JSONObject hellojson() {
JSONObject jo = new JSONObject();
jo.put("err","0");
jo.put("title","1");
jo.put("desc","2");
return jo;
}
2.4.2 List做返回值
@GetMapping(value="/jsondata",produces="application/json;charset=UTF-8")
@ResponseBody
public List<User> hellojson() {
User user = new User();
user.setUsername("jack");
user.setPassword("112233");
user.setHobbies(Arrays.asList(new String[]{"singing", "dancing", "football"}));
Map<String, String> maps = new HashMap<>();
maps.put("1", "o");
maps.put("2", "g");
maps.put("3", "a");
maps.put("4", "j");
user.setSecrets(maps);
List l = new ArrayList<>();
l.add(user);
return l;
}
输出为:
2.4.3 Map做返回值
@GetMapping(value="/jsondata",produces="application/json;charset=UTF-8")
@ResponseBody
public Map<String, String> hellojson() {
Map<String, String> maps = new HashMap<>();
maps.put("1", "o");
maps.put("2", "g");
maps.put("3", "a");
maps.put("4", "j");
return maps;
}
结果为:
因为添加了@ResponseBody注解,所以返回的都会是文本类型,不会去templates下寻找view返回html。
@GetMapping(value="/jsondata",produces="application/json;charset=UTF-8"),是指get方法,且返回类型为json。
也可以直接使用@RestController=@Controller+@ResponseBody
上文中新建项目时,还引入了mysql和mybatis,下次将进行简单的增删改查,对数据进行操作。