• Spring Boot 设计目的是用来简化新Spring 应用的初始搭建以及开发过程。
• 嵌入的Tomcat,无需部署WAR 文件
• Spring Boot 并不是对Spring 功能上的增强,而是提供了一种快速使用Spring 的方式。
选择的是jar项目
需要在创建时手动添加SpringBoot父项目
本博文所有演示案例都是基于本步骤,故在下面不做重复讲解,如果有变会特别贴出
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.10.RELEASEversion>
parent>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
注意
使用SpringBoot 1.5.10需要Jdk 1.7及以上 ,如果没有达到需要手动配置jdk版本 ,代码如下
<properties>
<java.version>1.7java.version>
properties>
<dependencies>
package ah.szxy.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloWorld {
@RequestMapping("/helloworld")
@ResponseBody
public Map<String,Object> showPage() {
Map<String, Object>map=new HashMap<String, Object>();
map.put("msg", "helloWorld");
return map;
}
}
@SpringBootApplication 表示当前项目是一个SpringBoot项目
package ah.szxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* SpringBoot 启动器
* @author chy
*
*/
@SpringBootApplication
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}
右击启动器 ,Run as JavaApplication
访问 ; http://localhost:8080/helloworld
启动器所在位置必须和controller 位于同一级包下(如下图),或者位于controller 的上一级包中,但是不能放到controller 子包下以及其他包,如Dao包或者Serrvice包。
启动器名称 | 作用 |
---|---|
spring-boot-starter-web | 支持全栈式的web 开发,包括了romcat 和springMVC 等jar |
spring-boot-starter-jdbc | 支持spring 以jdbc 方式操作数据库的jar 包的集合 |
spring-boot-starter-redis | 支持redis 键值存储的数据库操作 |
spring-boot-starter-test | SpringBoot支持单元集成测试的启动器 |
spring-boot-starter-thymeleaf | SpringBoot的支持 thymeleaf 语法(类似el表达式 )的启动器 |
spring-boot-starter-cache | Spring Boot 缓存支持启动器 |
同上
同上
常规方式 ,通过注解注入Servlet的name与访问路径 ,然后启动器如以往一样
创建Servlet
@WebServlet(name=“FirstServlet”,urlPatterns="/first")
相当于在web.xml中创建了servlet的name以及访问路径
package ah.szxy.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*SpringBoot整合Servlet方式一
*@WebServlet(name="FirstServlet",urlPatterns="/first")相当于如下:
*
*
* FirstServlet
* ah.szxy.servlet.FirstServlet
*
*
* FirstServlet
* /first
*
*
*/
@WebServlet(name="FirstServlet",urlPatterns="/first")
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("FirstServlet............");
}
}
创建启动器类
@SpringBootApplication 表示该程序时SpringBoot启动程序
@ServletComponentScan 表示 在springBoot启动时会扫描@WebServlet,并将该类实例化
package ah.szxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* SpringBoot整合Servlet方式一
*
*
*/
@SpringBootApplication
@ServletComponentScan //在springBoot启动时会扫描@WebServlet,并将该类实例化
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}
运行结果
访问 http://localhost:8080/first
servlet代码如同javaEE时一样 ,但是启动器创建了一个获取Servlet注册的Bean的方法 ,
通过@bean 标签,相当于在配置文件中配置了servlet的访问路径
创建Servlet
/**
*SpringBoot整合Servlet方式二
*
*/
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("SecondServlet..........");
}
}
创建启动器类
@bean 标签,相当于在配置文件中配置了servlet的访问路径
/**
* SpringBoot整合Servlet方式二
*
*
*/
@SpringBootApplication
public class Client2 {
public static void main(String[] args) {
SpringApplication.run(Client2.class, args);
}
@Bean
public ServletRegistrationBean getServletRegistrationBean(){
ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
bean.addUrlMappings("/second");
return bean;
}
}
运行结果
访问 :http://localhost:8080/second
这两种方法实现的功能都是一样的, 但是我们在实际开发中都比较推荐使用注解的方式, 后面的过滤器 以及监听器亦是如此 . 方法二太累赘,基本没人用了。而在学习中使用方法二其实是为了让大家更好的理解框架
本项目是基于上一个项目 ,两个Servlet程序不变 ,在此基础上添加了两个过滤器
创建Filter
@WebFilter(filterName=“FirstFilter”,urlPatterns="/first") ,表示在web.xml注册Filter ,过滤器名字为FirstFilter ,拦截的url是 /first
package ah.szxy.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* SpringBoot整合Filter方式一
* @author chy
*
*/
@WebFilter(filterName="FirstFilter",urlPatterns="/first")
public class FirstFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
System.out.println("进入过滤器");
arg2.doFilter(arg0, arg1);
System.out.println("离开过滤器");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
创建启动类
package ah.szxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* SpringBoot整合Servlet方式一
*
*
*/
@SpringBootApplication
@ServletComponentScan //在springBoot启动时会扫描@WebServlet,并将该类实例化
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}
创建Filter
public class SecondFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
System.out.println("进入Filter");
arg2.doFilter(arg0, arg1);
System.out.println("离开Filter");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
创建启动类
通过@Bean注册filter
@SpringBootApplication
public class Client2 {
public static void main(String[] args) {
SpringApplication.run(Client2.class, args);
}
@Bean
public ServletRegistrationBean getServletRegistrationBean() {
ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
bean.addUrlMappings("/second");
return bean;
}
/**
* 注册Filter
*/
@Bean
public FilterRegistrationBean getFilterRegistrationBean() {
FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter());
// bean.addUrlPatterns(new String[]{"*.do","*.jsp"});//拦截多个时
bean.addUrlPatterns("/second");
return bean;
}
}
运行结果
创建Filter
package ah.szxy.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* springBoot 整合Listener
* @WebListener 自动注册,相当于在web.xml中添加如下代码
*
*
* ah.szxy.listener.FirstListener
*
*/
@WebListener
public class FirstListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
System.out.println("FirstListener.contextDestroyed(上下文监听器)");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
System.out.println("FirstListener.contextInitialized(上下文监听器)");
}
}
创建启动类
@ServletComponentScan 在springBoot启动时会扫描@WebServlet,并将该类实例化
没有Servlet或没有Servlet使用@WebServlet 就不需要使用@ServletComponentScan注解
package ah.szxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}
创建Filter
package ah.szxy.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SecondListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
System.out.println("SecondListener.contextDestroyed(上下文监听器)");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
System.out.println("SecondListener.contextInitialized(上下文监听器)");
}
}
创建启动类
@SpringBootApplication
public class Client2 {
public static void main(String[] args) {
SpringApplication.run(Client2.class, args);
}
/**
* 注册listener
*/
@Bean
public ServletListenerRegistrationBean<SecondListener> getServletListenerRegistrationBean() {
ServletListenerRegistrationBean<SecondListener> bean = new ServletListenerRegistrationBean<SecondListener>(
new SecondListener());
return bean;
}
}
运行结果
注意目录名称必须是static
启动类
@SpringBootApplication
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}
访问 http://localhost:8080/images/1.png
需要将 src 创建webapp目录 ,在src目录创建静态资源
建议使用这一种方式进行静态资源的存放 ,方便后面的文件上传以及对视图层的整合
<body>
<h1>静态资源访问方式一h1><hr>
<img alt="" src="images/2.png">
body>
@SpringBootApplication
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}
package ah.szxy.util;
import java.util.Random;
import java.util.UUID;
/**
* 各种id生成策略
* @version 1.0
*/
public class IDUtils {
/**
* 图片名生成
*/
public static String genImageName() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//long millis = System.nanoTime();
//加上三位随机数
Random random = new Random();
int end3 = random.nextInt(1000);
//如果不足三位前面补0
String str = millis + String.format("%03d", end3);
return str;
}
/**
* 商品id生成
*/
public static long genItemId() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//long millis = System.nanoTime();
//加上两位随机数
Random random = new Random();
int end2 = random.nextInt(99);
//如果不足两位前面补0
String str = millis + String.format("%02d", end2);
long id = new Long(str);
return id;
}
public static void main(String[] args) {
for(int i=0;i< 100;i++)
System.out.println(genItemId());
}
}
application.properties
文件上传大小默认是10MB ,需要手动对上传大小进行修改
spring.http.multipart.maxFileSize=200MB
spring.http.multipart.maxRequestSize=200MB
属性 | 作用 |
---|---|
设置单个上传文件的大小 | spring.http.multipart.maxFileSize |
设置一次请求上传文件的总容量 | spring.http.multipart.maxRequestSize |
需要在webapp目录下 ,创建一个images的文件夹
package ah.szxy.controller;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import ah.szxy.util.IDUtils;
/**
* SpringBoot 文件上传
*
*
*/
@RestController // 表示该类下的方法的返回值会自动做json 格式的转换
public class FileUpLoadController {
/**
* 处理文件上传___上传到本地
*/
@RequestMapping("/fileUpLoad")
public Map<String, Object> fileUpload(MultipartFile file) throws Exception {
System.out.println(file.getOriginalFilename());
//放在e盘下
file.transferTo(new File("e:/" + file.getOriginalFilename()));
Map<String, Object> map = new HashMap<>();
map.put("msg", "ok");
return map;
}
/**
* 处理文件上传___上传到本项目images目录下
*/
@RequestMapping("/fileUpLoadToProject")
public String fileUpLoadToProject(MultipartFile file,HttpSession session) {
//通过session获取绝对路径,方法内部加上/WEB-INF/images,表示在项目的images目录下,需要创建该文件夹并进行静态资源放行
String path=session.getServletContext().getRealPath("/images");
String fileName = file.getOriginalFilename();//这个就是文件的路径
File file2 = new File(path, fileName );
try {
file.transferTo(file2);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//将文件的路径放到类属性中,修改此处
//goods.setPicture(fileName);
System.out.println(fileName);
return "ok";
}
/**
* 处理文件上传___上传到本项目images目录下,且名字随机
*/
@RequestMapping("/fileUpLoadToProjectAndNameRandom")
public String fileUpLoadToProjectAndNameRandom(MultipartFile file, HttpSession session) {
boolean flag=false;//上传结果
String filename=null;//上传后文件的名称
try {
filename=IDUtils.genImageName();
//原始文件名
String originalFilename = file.getOriginalFilename();
String ext = originalFilename.substring(originalFilename.lastIndexOf("."));//.之前的去掉
filename=filename+ext;
System.out.println("filename"+filename);
//通过工具类上图片
String path=session.getServletContext().getRealPath("/images");
File fileName = new File(path, filename );
try {
file.transferTo(fileName);
flag=true;
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
if (flag) {
System.out.println("ok");
}else {
System.out.println("false");
}
return "ok";
}
}
注意
表单提交的方式为 : post
enctype的值为 : multipart/form-data
file类型的输入框的name属性要和 MultipartFile 的形参一样 ,这样才能进行文件的上传
<body>
<h1>文件上传到本地e盘h1><hr>
<form action="/fileUpLoad" method="post" enctype="multipart/form-data">
<input type="file" name="file" ><br>
<input type="submit" value="点击上传">
form>
<h1>文件上传到本项目h1><hr>
<form action="/fileUpLoadToProject" method="post" enctype="multipart/form-data">
<input type="file" name="file" ><br>
<input type="submit" value="点击上传">
form>
<h1>文件上传到本项目名字随机h1><hr>
<form action="/fileUpLoadToProjectAndNameRandom" method="post" enctype="multipart/form-data">
<input type="file" name="file" ><br>
<input type="submit" value="点击上传">
form>
body>
Spring Boot 第三章(视图层技术)
父项目
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.10.RELEASEversion>
parent>
因为SpringBoot不是特别支持Jsp ,所以要使用时需要加上额外添加相关的坐标支持
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
dependency>
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-jasperartifactId>
<scope>providedscope>
dependency>
dependencies>
作用类似视图解析器
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
/**
* SpringBoot整合Jsp
* @author chy
*
*/
@Controller // 之所以不要@RestController是因为要进行页面的跳转而不是发送json格式字符串
public class UserController {
/*
* 处理请求,产生数据
*/
@RequestMapping("/showUser")
public String showUser(Model model){
List<Users> list = new ArrayList<>();
list.add(new Users(1,"鸣人",20));
list.add(new Users(2,"佐助",22));
list.add(new Users(3,"小樱",24));
//需要一个Model 对象
model.addAttribute("list", list);
//跳转视图
return "userList";
}
}
使用 jstl 需要在 jsp页面开始加入jstl 核心标签库
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<body>
<table border="1" align="center" width="50%">
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
</tr>
<c:forEach items="${list }" var="user">
<tr>
<td>${user.userid }</td>
<td>${user.username }</td>
<td>${user.userage }</td>
</tr>
</c:forEach>
</table>
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
父项目
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.10.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-freemarkerartifactId>
dependency>
dependencies>
建议使用HBuilder编写改代码 ,方式如下
打开目录 ,在java工作空间找到该项目
注意:
springBoot 要求模板形式的视图层技术的文件必须要放到src/main/resources 目录下必须要一个名称为templates
视图层代码
userList.ftl
展示用户数据
ID
Name
Age
<#list list as user>
${user.userid}
${user.username}
${user.userage}
#list>
@Controller // 之所以不要@RestController是因为要进行页面的跳转而不是发送json格式字符串
public class UserController {
/*
* 处理请求,产生数据
*/
@RequestMapping("/showUser")
public String showUser(Model model){
List<Users> list = new ArrayList<>();
list.add(new Users(1,"鸣人",20));
list.add(new Users(2,"佐助",22));
list.add(new Users(3,"小樱",24));
//需要一个Model 对象
model.addAttribute("list", list);
//跳转视图
return "userList";
}
}
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
父项目
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.10.RELEASEversion>
parent>
<properties>
<thymeleaf.version>3.0.2.RELEASEthymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.4thymeleaf-layout-dialect.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
dependencies>
不能直接访问视图层html页面,只能通过controller来跳转到对应的页面!!!
如果想直接访问页面需要添加一个页面访问的Controller
@Controller
public class PageController {
@RequestMapping("/{page}")
public String showPage(@PathVariable String page) {
return page;
}
}
<html>
<head>
<meta charset="UTF-8">
<title>Thymeleaf 入门title>
head>
<body>
<span th:text="Hello">span>
<hr />
<span th:text="${msg}">span>
body>
html>
@Controller
public class ThymeleafController {
@RequestMapping("/showPage")
public String showInfo(Model model) {
model.addAttribute("msg", "Thymeleaf的入门案例");
return "index";
}
}
/**
* 启动Thymeleaf入门案例
* @author chy
*
*/
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
语法 | 作用 |
---|---|
th:value | 在页面中输出值 |
th:value | 可以将一个值放入到input 标签的value 中 |
注意语法:
1,调用内置对象一定要用#
2,大部分的内置对象都以s 结尾strings、numbers、dates
语法 | 作用 |
---|---|
${#strings.isEmpty(key)} | 判断字符串是否为空,如果为空返回true,否则返回false |
${#strings.contains(msg,‘T’)} | 判断字符串是否包含指定的子串,如果包含返回true,否则返回false |
${#strings.startsWith(msg,‘a’)} | 判断当前字符串是否以子串开头,如果是返回true,否则返回false |
${#strings.endsWith(msg,‘a’)} | 判断当前字符串是否以子串结尾,如果是返回true,否则返回false |
${#strings.length(msg)} | 返回字符串的长度 |
${#strings.indexOf(msg,‘h’)} | 查找子串的位置,并返回该子串的下标,如果没找到则返回-1 |
${#strings.substring(msg,13)} ${#strings.substring(msg,13,15)} |
截取子串,用户与jdk String 类下SubString 方法相同 |
${#strings.toUpperCase(msg)} ${#strings.toLowerCase(msg)} |
字符串转大小写。 |
语法 | 作用 |
---|---|
${#dates.format(key)} | 格式化日期,默认的以浏览器默认语言为格式化标准 |
${#dates.format(key,‘yyy/MM/dd’)} | 按照自定义的格式做日期转换 |
${#dates.year(key)} ${#dates.month(key)} ${#dates.day(key)} |
获取具体的年月日信息 year:取年 Month:取月Day:取日 |
if语句__th:if
<span th:if="${sex} == '男'">
性别:男
</span>
<span th:if="${sex} == '女'">
性别:女
</span>
switch语句__th:switch
<span th:switch="${id}">
<span th:case="1">ID为1</span>
<span th:case="2">ID为2</span>
<span th:case="3">ID为3</span>
</span>
@RequestMapping("/show2")
public String showOther2(Model model) {
List<Users> list=new ArrayList<Users>();
list.add(new Users(1, "秦小敏", 16));
list.add(new Users(2, "沙小光", 17));
list.add(new Users(3, "超叔", 18));
model.addAttribute("list", list);
return "index3";
}
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
<th>Index</th>
<th>Count</th>
<th>Size</th>
<th>Even</th>
<th>Odd</th>
<th>First</th>
<th>lase</th>
</tr>
<tr th:each="u,var : ${list}">
<td th:text="${u.userid}"></td>
<td th:text="${u.username}"></td>
<td th:text="${u.userage}"></td>
<td th:text="${var.index}"></td>
<td th:text="${var.count}"></td>
<td th:text="${var.size}"></td>
<td th:text="${var.even}"></td>
<td th:text="${var.odd}"></td>
<td th:text="${var.first}"></td>
<td th:text="${var.last}"></td>
</tr>
</table>
状态变量 | 作用 |
---|---|
index | 当前迭代器的索引从0 开始 |
count | :当前迭代对象的计数从1 开始 |
size | :被迭代对象的长度 |
even/odd | 布尔值,当前循环是否是偶数/奇数从0 开始 |
first | 布尔值 ,当前循环的是否是第一条,如果是返回true 否则返回false |
last | 布尔值,当前循环的是否是最后一条,如果是则返回true 否则返回false |
@RequestMapping("/show3")
public String showOther3(Model model) {
Map<String, Users>map=new HashMap<String, Users>();
map.put("u1", new Users(1, "秦小敏", 16));
map.put("u2", new Users(2, "沙小光", 17));
map.put("u3", new Users(3, "超叔", 18));
model.addAttribute("map", map);
return "index4";
}
<table border="1" align="center">
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
</tr>
<tr th:each="maps:${map}">
<td th:each="entry:${maps}" th:text="${entry.value.userid}"></td>
<td th:each="entry:${maps}" th:text="${entry.value.username}"></td>
<td th:each="entry:${maps}" th:text="${entry.value.userage}"></td>
</tr>
</table>
@RequestMapping("/show4")
public String showOther4(HttpServletRequest req,Model model) {
req.setAttribute("req", "HttpServletRequest");//request对象
req.getSession().setAttribute("sess", "sesssion");//session对象
return "index5";
}
body>
<!-- 获取request作用域对象 -->
<span th:text="${#httpServletRequest.getAttribute('req')}"></span><br>
<!-- 获取session对象 -->
<span th:text="${session.sess}"></span>
</body>
分类
th:href
th:src
url 表达式语法
基本语法:@{}
@Controller
public class ThymeleafController {
@RequestMapping("/{page}")
public String showPage(@PathVariable String page,Integer id) {
System.out.println(id);
return page;
}
<body>
<!-- 绝对路径 ,跳转到b站 -->
<a href="http://www.bilibili.com">绝对路径</a><br>
<a th:href="@{http://www.bilibili.com}">Thymeaf绝对路径</a>
<br>
<!-- 相对路径 ,跳转到名为 show.html的页面 -->
<a th:href="@{/show}">相对路径</a><br>
<!-- 相当于在tomcat的根目录下查找 -->
<a th:href="@{~/project2/resourcename}">相对于服务器的根</a><br>
<!-- 在url 中实现参数传递 -->
<a th:href="@{/show(id=1,name=zhagnsan)}">相对路径-传参</a><br>
<!-- 在url 中通过restful 风格进行参数传递 -->
<a th:href="@{/path/{id}/show(id=1,name=zhagnsan)}"> 相对路径- 传参-restful</a>
</body>
创建项目时 ,需要继承SpringBoot启动器的父类 (可以在下面pom文件中找) ,选择maven 的jar项目
<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">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.10.RELEASEversion>
parent>
<groupId>ah.szxy.SpringBootgroupId>
<artifactId>12-SpringBoot-SpringMVC-MybatisartifactId>
<version>0.0.1-SNAPSHOTversion>
<properties>
<thymeleaf.version>3.0.2.RELEASEthymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.4thymeleaf-layout-dialect.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.1.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.0.9version>
dependency>
dependencies>
project>
在resource目录下
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ssm
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.type-aliases-package=ah.szxy.pojo
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`userage` int(11) DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
package ah.szxy.pojo;
public class Users {
private int userid;
private String username;
private int userage;
//取值赋值方法以及带参无参构造方法自行添加
}
public interface UsersMapper {
/**
* 添加用户
* @param users
*/
void insertUser(Users users);
/**
* 查询所有用户
* @return
*/
List<Users> findAllUser();
/**
* 通过id查询用户
* @param userid
*/
Users findUserById(Integer userid);
/**
* 更新
* @param users
*/
void updateUser(Users users);
/**
* 删除
* @param userid
*/
void deleteUser(Integer userid);
}
<mapper namespace="ah.szxy.mapper.UsersMapper">
<insert id="insertUser" parameterType="users">
insert into users(username,userage) values(#{username},#{userage})
insert>
<select id="findAllUser" resultType="users">
select * from users
select>
<select id="findUserById" resultType="users">
select * from users where userid=#{userid}
select>
<update id="updateUser" parameterType="users">
update users set username=#{username},userage=#{userage} where userid=#{userid}
update>
<delete id="deleteUser" parameterType="users">
delete from users where userid=#{userid}
delete>
mapper>
public interface UsersService {
void insertUser(Users users);
List<Users> findAllUser();
Users findUserById(Integer userid);
void updateUser(Users users);
void deleteUser(Integer userid);
}
@Service
public class UsersServiceImpl implements UsersService{
@Autowired
private UsersMapper usersMapper;
@Override
public void insertUser(Users users) {
this.usersMapper.insertUser(users);
}
@Override
public List<Users> findAllUser() {
return this.usersMapper.findAllUser();
}
@Override
public Users findUserById(Integer userid) {
return this.usersMapper.findUserById(userid);
}
@Override
public void updateUser(Users users) {
this.usersMapper.updateUser(users);
}
@Override
public void deleteUser(Integer userid) {
this.usersMapper.deleteUser(userid);
}
}
页面跳转Controller
@Controller
public class PageController {
@RequestMapping("/{page}")
public String showPage(@PathVariable String page) {
return page;
}
}
具体业务功能实现的Controller
注意 :如果需要从Controller中的一个方法跳转到另一个方法 ,则和SpringMVC一样, 列如 return "redirect:findAll";
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
@RequestMapping("/add")
public String addUser(Users users) {
this.usersService.insertUser(users);
return "ok";
}
@RequestMapping("/findAll")
public String findAllUser(Model model) {
List<Users>list=this.usersService.findAllUser();
model.addAttribute("list", list);
return "findAllUser";
}
@RequestMapping("/findUser")
public String findUserById(Integer userid,Model model) {
Users user = this.usersService.findUserById(userid);
model.addAttribute("user", user);
return "updateUser";
}
@RequestMapping("/update")
public String updateUser(Users users) {
this.usersService.updateUser(users);
return "ok";
}
@RequestMapping("/delete")
public String deleteUser(Integer userid) {
this.usersService.deleteUser(userid);
return "redirect:findAll";
}
}
注意 :
1.页面后缀全部都是 .html而不是jsp ,使用的是 ThymeLeaf 可以对 Html页面进行传值操作
2. 下面代码可用于点击用户时将用户id信息传入对应的Controller的方法中
<a th:href="@{/user/findUser(userid=${user.userid})}">
addUser.html
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>
<form th:action="@{/user/add}">
用户姓名: <input type="text" name="username"><br>
用户年龄: <input type="text" name="userage"><br>
<input type="submit" value="添加">
form>
body>
html>
findAllUser.html
<html>
<head>
<meta charset="UTF-8">
<title>用户查询界面title>
head>
<body>
<table border="1" style="width: 400px" align="center">
<tr>
<th>用户idth>
<th>用户姓名th>
<th>用户年龄th>
<th>操作th>
tr>
<tr th:each="user:${list}">
<td th:text="${user.userid}">td>
<td th:text="${user.username}">td>
<td th:text="${user.userage}">td>
<td><a th:href="@{/user/findUser(userid=${user.userid})}">更新a>
<a th:href="@{/user/delete(userid=${user.userid})}">删除a>
td>
tr>
table>
body>
html>
ok.html
<html>
<head>
<meta charset="UTF-8">
<title>操作提示页面title>
head>
<body>
<h1>操作成功h1>
body>
html>
updateUser.html
<html>
<head>
<meta charset="UTF-8">
<title>用户更新页面title>
head>
<body>
<form th:action="@{/user/update}">
<input type="hidden" name="userid" th:field="${user.userid}">
用户姓名: <input type="text" name="username" th:field="${user.username}"><br>
用户年龄: <input type="text" name="userage" th:field="${user.userage}"><br>
<input type="submit" value="更新">
form>
body>
html>