RequestMapping 和 Delete 请求方法的组合 只支持 Delete 请求 通常用于删除数据
/** * 该案例主要演示了使用 Spring 提供的不同注解接收不同类型的请求 */ //RestController 注解相当于加了给方法加了@ResponseBody 注解,所以是不能跳转页面的, 只能返回字符串或者 json 数据 @RestController public class MVCC ontroller { @GetMapping(value = "/query") public String get() { return "@GetMapping 注解,通常查询时使用"; } @PostMapping(value = "/add") public String add() { return "@PostMapping 注解,通常新增时使用"; } @PutMapping(value = "/modify") public String modify() { return "@PutMapping 注解,通常更新数据时使用"; } @DeleteMapping(value = "/remove") public String remove() { return "@DeleteMapping 注解,通常删除数据时使用"; } }
在SpringBoot中核心配置文件一般只有一个。如果这两种核心配置文件同时存在,那项目会优先读取application.properties中的配置文件。
设置内嵌tomcat内嵌端口号:
server.port=9090
设置上下文根
server.servlet.context-path=/txzmy
修改前
修改后:
设置内嵌tomcat端口号和上下文根:
在使用这种方式时,先删除application.properties,后新建一个file,核心文件的命名必须以application开头。这种方式类似与python的缩进。
server: port: 9090 servlet: context-path: /txzmy
工作中的四种环境:开发环境,测试环境,准生产环境,生产环境。在不同的环境下同一个网页的访问网址不同,核心文件配置不同。
添加其他环境下的核心配置文件必须以application-开头。
#主核心配置文件 #激活使用的配置文件 #等号后面只需要跟已定的核心配置文件的名称 spring.profiles.active=dev
三种不同文件类型的核心配置文件写法相似。
我们可以在核心配置文件或者其他文件里设置一些值,通过注解@value可以访问到这些值。
#主核心配置文件 #激活使用的配置文件 spring.profiles.active=dev #设置自定义的值 schoolName=CTGU stuName=tx #方法类 package com.txzmy.springboot; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @Controller public class Index { @Value("${schoolName}") public String schoolName; @Value("${stuName}") public String stuName; @RequestMapping(value = "/hello") public @ResponseBody String hello() { return "hello,"+stuName+" from "+schoolName; } }
通过域名http://localhost:7070/dev/hello访问结果:hello,tx from CTGU
在用@Value时我们只能一个一个的取值,我们可以通过@Component和@ConfigurationProperties将文件中的值映射到对象中。配置对象必须有统一的前缀。直接上代码:
#主核心配置文件 #激活使用的配置文件 spring.profiles.active=dev #设置自定义的值 school.Name=CTGU school.stuName=tx //被映射的类 #package com.txzmy.springboot; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; //将拿到的值交给spring容器管理 @Component //@ConfigurationProperties必须有个前缀,即上面设置的自定义值的前缀,后面可以不带这个前缀。 @ConfigurationProperties(prefix = "school") public class school { private String Name; private String stuName; public String getName() { return Name; } public void setName(String name) { Name = name; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } } //方法类 package com.txzmy.springboot; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @Controller public class Index { @Autowired public school school; @RequestMapping(value = "/hello") public @ResponseBody String hello() { return "hello,"+school.getStuName()+" from "+school.getName(); } }
运行结果:hello,tx from CTGU
<!-- 引入SpringBoot内嵌的Tomcat对JSp的解析依赖,不添加解析不了--> <!-- 在这里我们仅仅展示JSP页面,只添加下面一个依赖--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jsper</artifactId> </dependency>
<build> <!-- Springboot项目默认推荐使用的前端引擎是thymeleaf 现在我们要使用springboot集成jsp,手动指定jsp最后编译的路径 而且springboot集成jsp编译jsp的路径是springboot规定好的位置 MFTA-TNF /resources --> <resources> <resource> <!-- 源文件夹--> <directory>src/main/webapp</directory> <!--指定编译到META-INF/reserous--> <targetPath>META-INF/reserous</targetPath> <!--指定源文件夹的那个文件要编译--> <includes> <include>*.*</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
核心配置文件:application.properties
#配置视图解析器 #配置前缀 spring.mvc.view.prefix=/ #配置后缀 spring.mvc.view.suffix=/jsp
@Controller public class Index { @RequestMapping(value = "/hello") public ModelAndView hello() { ModelAndView mv = new ModelAndView(); mv.addObject("message","Hello SpringBoot"); mv.setViewName("hello"); return mv; } }
<!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--MyBatis整合SpringBoot框架的起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency>
Mybatis提供的逆向工程可以生成实体bean,映射文件,DAO接口:
需要添加的配置文件:
在项目的根目录下添加GeneratorMapper.xml文件,文件具体内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 --> <classPathEntry location="D:/mysql-downloads/mysql-connector-java-5.1.49/mysql-connector-java-5.1.49/mysql-connector-java-5.1.49.jar"/> <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 --> <context id="txzmy" targetRuntime="MyBatis3"> <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 --> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator> <!-- 配置数据库连接信息 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306" userId="root" password="Tx110304.."> </jdbcConnection> <!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定 生成的 model 放在 eclipse 的哪个工程下面--> <javaModelGenerator targetPackage="comzmy.model" targetProject="src/main/java"> <property name="enableSubPackages" value="false" /> <property name="trimStrings" value="false" /> </javaModelGenerator> <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的 包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 --> <sqlMapGenerator targetPackage="comzmy.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包 名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 --> <javaClientGenerator type="XMLMAPPER" targetPackage="comzmy.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 数据库表名及对应的 Java 模型类名 --> <table tableName="student" domainObjectName="Student" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/> </context> </generatorConfiguration>
在项目文件pom.xml中添加依赖:
<!--MyBatis 集成 SpringBoot 框架起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <!--MySQL 驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <!--指定配置资源的位置--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> <plugins> <!--mybatis 代码自动生成插件--> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.6</version> <configuration> <!--配置文件的位置--> <configurationFile>GeneratorMapper.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> </plugins>
在application.properties文件中配置数据库的相关信息:
#配置内嵌 Tomcat 端口号 server.port=9090 #配置项目上下文根 server.servlet.context-path=/txzmy #配置数据库的连接信息 #注意这里的驱动类有变化 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=Tx110304..
在右侧maven结构中选择Plugins->mybatis-generator->mybatis-generator:generate.双击mybatis-generator:generate.
Spring boot 开发 RESTFul 主要是几个注解实现:
pom.xml添加内容:
<dependencies> <!--SpringBoot 框架 web 项目起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--MyBatis 集成 SpringBoot 框架起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <!--MySQL 驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <!--指定配置资源的位置--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> <plugins> <!--mybatis 代码自动生成插件--> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.6</version> <configuration> <!--配置文件的位置--> <configurationFile>GeneratorMapper.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
application.yml 核心配置文件:
server: port: 8090 #设置 Tomcat 内嵌端口号 servlet: context-path: / #设置上下文根 #配置数据源 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBC CompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 username: root password: Tx110304..
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 [1]
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
在Pom.xml添加操作redis数据类型的依赖:
<!--SpringBoot集成Redis的起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
在SpringBoot核心配置文件中添加Redis的 配置(配置连接信息):
#redis连接信息 spring.redis.host= sring.redis.port= sring.redis.password=
RestController类:
@RestController public class RedisController { @Autowired private StudentService studentService; @GetMapping(value = "/springboot/allStudentCount") public Object allStudentCount(HttpServletRequest request) { Long allStudentCount = studentService.queryAllStudentCount(); return "学生总人数:" + allStudentCount; } }
StudentService 接口:
public interface StudentService { /** * 获取学生总人数 * @return */ Long queryAllStudentCount(); }
在 StudentServiceImpl 中注入 RedisTemplate 并修改根据 id 获取学生的方法:
@Service public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper studentMapper; @Autowired private RedisTemplate<Object,Object> redisTemplate; @Override public Long queryAllStudentCount() { //设置 redisTemplate 对象 key 的序列化方式 redisTemplate.setKeySerializer(new StringRedisSerializer()); //从 redis 缓存中获取总人数 Long allStudentCount = (Long) redisTemplate.opsForValue().get("allStudentCount"); //判断是否为空 if (null == allStudentCount) { //去数据库查询,并存放到 redis 缓存中 allStudentCount = studentMapper.selectAllStudentCount(); redisTemplate.opsForValue().set("allStudentCount",allStudentCount,15, TimeUnit.SECONDS); } return allStudentCount; } }
StudentMapper 接口:
public interface StudentMapper { /** * 获取学生总人数 * @return */ Long selectAllStudentCount(); }
StudentMapper 映射文件:
<!--获取学生总人数--> <select id="selectAllStudentCount" resultType="java.lang.Long"> select count(*) from t_student </select>
启动类 Application:
在 SpringBoot 启动类上添加扫描数据持久层的注解并指定扫描包:
@SpringBootApplication @MapperScan(basePackages = "com.txzmy.mapper")//扫描数据持久层 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
创建一个Maven空项目,作为项目的父工程,此工程的子项目基于Spring Boot 2.0.5 实现
在父工程的pom.xml引入之后要创建的子工程
<modules> <module>gmall-interface</module> <module>user-service-provider</module> <module>order-service-consumer</module> </modules>
可以提前看一下工程结构
下面分别来实现子工程:(子工程的实现方式都是在gmall工程下新建Module)
项目中共用的接口和POJO类,代码和之前一样,这里不再展开
工程结构如下
引入依赖
<!-- 引入公共API,以实现其接口 --> <dependency> <groupId>com.zang</groupId> <artifactId>gmall-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 引入spring-boot-starter以及dubbo和curator的依赖 --> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency> <!-- Spring Boot相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
需要注意的是,根据jdk和Spring Boot版本的不同,dubbo-spring-boot-starter的版本需要有根据的选择
dubbo提供了@Service注解,可将类声明为提供方,省去了大量配置的麻烦
import com.alibaba.dubbo.config.annotation.Service; import com.zang.gmall.bean.UserAddress; import com.zang.gmall.service.UserService; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; @Service //属于Dubbo的@Service注解,非Spring 作用:暴露服务 @Component public class UserServiceImpl implements UserService { @Override public List<UserAddress> getUserAddressList(String userId) { //省略 }}
通过属性配置的方式设置application.properties
#当前服务/应用的名字 dubbo.application.name=user-service-provider #注册中心的协议和地址 dubbo.registry.protocol=zookeeper dubbo.registry.address=127.0.0.1:2181 #通信规则(通信协议和接口) dubbo.protocol.name=dubbo dubbo.protocol.port=20880 #连接监控中心 dubbo.monitor.protocol=registry #开启包扫描,可替代 @EnableDubbo 注解 ##dubbo.scan.base-packages=com.zang.gmall
springboot容器根据配置启动服务提供方,这里需要添加 @EnableDubbo 注解
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; // 开启基于注解的dubbo功能(主要是包扫描@DubboComponentScan) // 也可以在配置文件中使用dubbo.scan.base-package来替代 @EnableDubbo @EnableDubbo @SpringBootApplication public class UserServiceProviderApplication { public static void main(String[] args) { SpringApplication.run(UserServiceProviderApplication.class, args); } }
提供方顺利启动
消费者工程在初始化时设置为web项目,结构如下
引入和服务提供方同样的依赖,除此之外,添加springboot web模块的依赖。
<!-- springboot web模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
dubbo提供了@Reference注解,可替换@Autowired注解,用于引入远程服务
import com.alibaba.dubbo.config.annotation.Reference; import com.zang.gmall.bean.UserAddress; import com.zang.gmall.service.OrderService; import com.zang.gmall.service.UserService; import org.springframework.stereotype.Service; import java.util.List; @Service public class OrderServiceImpl implements OrderService { @Reference UserService userService; @Override public List<UserAddress> initOrder(String userId) { //代码省略 }}
配置文件application.properties
#避免和监控中心端口冲突,设为8081端口访问 server.port=8081 dubbo.application.name=order-service-consumer dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.monitor.protocol=registry
启动类同样加上@EnableDubbo注解
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableDubbo @SpringBootApplication public class OrderServiceConsumerApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceConsumerApplication.class, args); } }
为查看调用是否成功,新增控制层用于访问
import com.zang.gmall.bean.UserAddress; import com.zang.gmall.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Controller public class OrderController { @Autowired OrderService orderService; @ResponseBody //以json格式返回 @RequestMapping("/initOrder") public List<UserAddress> initOrder(@RequestParam("uid") String userId){ return orderService.initOrder(userId); } }
启动消费方,在浏览器访问
调用成功
附:springboot也允许引用xml文件配置,方法是在启动类中加入如下注解
//@EnableDubbo //引入配置信息 @ImportResource(locations="classpath:provider.xml") @SpringBootApplication public class UserServiceProviderApplication { //略 }
直接在 main 方法中,根据 SpringApplication.run()方 法获取返回的 Spring 容器对象,再获取业务 bean 进行调用:
//Application.java文件 package com.txzmy; import com.txzmy.TestInterface1.UserService; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { /** * SpringBoot 程序启动后,返回值是 ConfigurableApplicationContext,它也是一个 Spring 容器对象 * 它其它相当于原来 Spring 中启动容器 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(""); */ //获取 SpringBoot 程序启动后的 Spring 容器 ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); //从 Spring 容器中获取指定 bean 的对象 UserService userService = (UserService) context.getBean("userServiceImpl"); //调用业务 bean 的方法 String sayHello = userService.SayHello(); System.out.println(sayHello); } } //UserService接口 package com.txzmy.TestInterface1; public interface UserService { String SayHello(); } //UserServiceImpl接口实现类 package com.txzmy.TestAchieve; import com.txzmy.TestInterface1.UserService; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService { @Override public String SayHello() { return "Hello"; } }
运行结果:
注意:
Spring boot 的入口类实现 CommandLineRunner 接口。
//Application.java文件 package com.txzmy; //import javafx.application.Application; import com.txzmy.TestInterface1.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private UserService userService; @Override // 重写CommandLineRunner中的run方法 public void run(String... args) throws Exception { System.out.println(userService.SayHello()); } public static void main(String[] args) { SpringApplication.run(Application.class); } } //接口类和接口实现类和上面相同
运行结果:
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); //关闭启动 logo 的输出 springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args); } }
定义一个拦截器,实现HandlerInterceptor接口。
package com.txzmy.interceptor; import com.txzmy.model.User; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("进入拦截器-----------------"); //编写业务中拦截的规则 //从session中获取用户的信息 User user = (User)request.getSession().getAttribute("user"); //判断用户是否登录 if(null==user) { response.sendRedirect(request.getContextPath()+"/user/error"); return false; } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
创建一个配置类(即:在SpringMvc配置文件中使用MVC:拦截器标签)。
package com.txzmy.config; import com.txzmy.interceptor.UserInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration //定义此类为配置文件(即相当于之前的xml配置文件) public class InterceptorConfig implements WebMvcConfigurer { @Override //拦截器注册类,需要我们把自己定义的拦截器注册进去 public void addInterceptors(InterceptorRegistry registry) { //定义需要拦截的和不需要拦截的String容器 //要拦截user下面的所有的访问请求,必须用户登录后才可以访问 String[] addPathPatterns={ "/user/**" }; //要排除的路径,排除的路径说明用户不需要登陆也可以访问 String[] excludePathPatterns={ "/user/out","/user/error","/user/login" }; registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns); } }
请求页面类:
package com.txzmy.web; import com.txzmy.model.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; @Controller @RequestMapping("/user") public class UserController { @RequestMapping(value = "/login") public @ResponseBody Object login(HttpServletRequest request) { //将用户信息放到session中 User user=new User(); user.setId(1001); user.setName("张满月"); request.getSession().setAttribute("user",user); return "login success"; } //该请求需要用户登录后才可以访问 @RequestMapping(value = "/center") public @ResponseBody Object center() { return "Center Message"; } //该请求不需要用户可以访问 @RequestMapping(value = "/out") public @ResponseBody Object out() { return "out Message"; } //如果用户未登录访问了需要登陆才可以访问的数据,会跳转至该请求 @RequestMapping(value = "/error") public @ResponseBody Object error() { return "error"; } }
用户类:
package com.txzmy.model; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
MyServlet.java
package com.example.demo.Servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; //定义访问的地址 @WebServlet(urlPatterns = "/myServlet") public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().print("My SpringBoot Servlet"); response.getWriter().flush(); response.getWriter().close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Application.java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication //开启Spring配置 @ServletComponentScan(basePackages = "com.example.demo.Servlet") //指定要扫描的Servlet public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
ServletConfiguration.java
package com.example.demo.Servlet; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ServletConfiguration { //@Bean 是一个方法级别上的注解,主要用在配置类里 /* * 相当于一个<beans> * <bean id="" class=""/> * </beans> * */ @Bean public ServletRegistrationBean servletRegistrationBean() { //将自定义 servlet 注册到注册 Servlet 类中,并指定访问路径 ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyServlet(), "/MyServlet"); return servletRegistrationBean; } }
MyServlet.java
package com.example.demo.Servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().print("My SpringBoot Servlet2222"); response.getWriter().flush(); response.getWriter().close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
application.java不变
MyFilter.java
@WebFilter(urlPatterns = "/springboot/myFilter") //设置过滤的访问路径 public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("-------------您已进入过滤器---------------"); filterChain.doFilter(servletRequest,servletResponse); } }
Application文件
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @ServletComponentScan(basePackages = "com.demo.filter") @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }
结果:通过 .../springboot/myFilter...的访问路径全部无法访问。
FilterConfiguration.java
package com.example.demo.Filter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.FilterRegistration; @Configuration public class FilterConfiguration { @Bean public FilterRegistrationBean myFilterRegistration (){ //注册过滤器 FilterRegistrationBean filterRegistrationBean =new FilterRegistrationBean(new MyFilter()); //添加过滤路径 filterRegistrationBean.addUrlPatterns("/User/*"); return filterRegistrationBean; } }
MyFilter.java
package com.example.demo.Filter; import javax.servlet.*; import java.io.IOException; public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("get access to filter"); filterChain.doFilter(servletRequest,servletResponse); } }
userController.java
package com.example.demo.Filter; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class userController { @RequestMapping(value = "/User/one") public @ResponseBody String one() { return "one"; } @RequestMapping(value = "/two") public @ResponseBody String two() { return "two"; } }
MyServlet.java
package com.example.demo.Servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class MyServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().println("张满月:Hello,demo"); //设置浏览器编码格式 resp.setContentType("text/html;character=utf-8"); resp.getWriter().flush(); resp.getWriter().close(); } }
配置类:
package com.example.demo.Servlet; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.CharacterEncodingFilter; @Configuration //定义此类为配置类 public class SystemConfiguration { @Bean public ServletRegistrationBean servletRegistrationBean() { ServletRegistrationBean servletRegistrationBean=new ServletRegistrationBean(new MyServlet(),"/Servlet/MyServlet"); return servletRegistrationBean; } @Bean public FilterRegistrationBean filterRegistrationBean() { //设置字符编码过滤器 //CharacterEncoding 是由 Spring 提供的一个字符编码过滤器,之前是配置在web.xml 文件中 CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); //强制使用指定字符编码 characterEncodingFilter.setForceEncoding(true); //设置指定字符编码 characterEncodingFilter.setEncoding("utf-8"); //创建过滤器注册 bean FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(); //设置字符编码过滤器 filterRegistrationBean.setFilter(characterEncodingFilter); //设置字符编码过滤器路径 filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } }
application.properties
#关闭 springboot 的 http 字符编码支持 #只有关闭该选项后,spring 字符编码过滤器才生效 server.servlet.encoding.enabled=false
不设置解码方式中文可能会乱码。
核心配置文件application.properties:
#设置请求响应的字符编码 spring.http.encoding.enabled=true spring.http.encoding.force=true spring.http.encoding.charset=UTF-8
MyServlet.java
package com.example.demo.Servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/ServletDemo") public class MyServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().println("张满月:Hello,demo"); //设置浏览器编码格式 resp.setContentType("text/html;character=utf-8"); resp.getWriter().flush(); resp.getWriter().close(); } }
在主类中定义扫描路径:
@SpringBootApplication @ServletComponentScan(basePackages = "com.example.demo.Servlet") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
未设置前:
设置后:
将SpringBoot的项目的打包方式设置为war:
<groupId>com.example</groupId> <artifactId>demo</artifactId> <version>1.0.0</version> <packaging>war</packaging>
移除内嵌的tomcat模块,但是为了我们在本机测试方便,我们还需要引入它,所以配置如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
添加tomcat-servelt-api依赖:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>7.0.42</version> <scope>provided</scope> </dependency>
修改入口方法 继承一个SpringBootServletInitializer类,并且覆盖configure方法:
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class SpringDataJpaExampleApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringDataJpaExampleApplication.class); } public static void main(String[] args) { SpringApplication.run(SpringDataJpaExampleApplication.class, args); } }
添加war插件,用来自定义打包以后的war包的名称:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <warSourceExcludes>src/main/resources/**</warSourceExcludes> <warName>springboot</warName> </configuration> </plugin>
右键startup文件,编辑,在文件头添加:
SET JAVA_HOME=D:java-web-springJAVAideaIU-2019jdk1.8.0_31 SET TOMCAT_HOME=D:java-web-springJAVAideaIU-2019apache-tomcat-9.0.21
两个路径分别为jdk的路径和tomcat的路径。shutdown文件闪退操作相同。
在 pom.xml 文件中添加 Tomcat 解析 jsp 依赖
<!--SpringBoot 项目内嵌 tomcat 对 jsp 的解析包--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency>
在 pom.xml 文件中添加 resources 配置,以后为了保险起见, 大家在打包的时候,建议把下面的配置都加上:
<resource> <!--源文件夹--> <directory>src/main/webapp</directory> <!--目标文件夹--> <targetPath>META-INF/resources</targetPath> <!--包含的文件--> <includes> <include>**/*.*</include> </includes> </resource> <!--mybatis 的 mapper.xml--> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <!--src/main/resources 下的所有配置文件编译到 classes 下面去--> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.*</include> </includes> </resource>
修改 application.properties 配置文件:
打jar包也将工程的核心配置文件一起打包,所以在核心配置文件里面设置的端口号起作用,而war包的上下文根是打包的项目名。
#设置内嵌 Tomcat 端口号 server.port=9090 #设置项目上下文根 server.servlet.context-path=/ #配置 jsp 的前/后缀 spring.mvc.view.prefix=/ spring.mvc.view.suffix=.jsp
➢在 IDEA 中直接运行 Spring Boot 程序的 main 方法(开发阶段)
用 maven 将 Spring Boot 安装为一个 jar 包,使用 Java 命令运行
java -jar springboot-xxx.jar
可以将该命令封装到一个 Linux 的一个 shell 脚本中(上线部署)
#设置themeleaf模板引擎的前后缀 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html
#设置缓存,默认为开启,建议在开发阶段关闭 thymeleaf 页面缓存,目的实时看到页面 spring.thymeleaf.cache=false
让页面随源码的改动而改变:
关掉thymeleaf缓存;
在Run/Debug Configurations窗口中修改On 'Update' action和On frame deactivation为Update resources.
相关实现:
//控制类 @Controller public class ThymeleafController { @RequestMapping(value = "/thymeleaf/index") public String index(Model model) { model.addAttribute("data","SpringBoot 成功集成 Thymeleaf 模版!"); return "index"; } }
//thymeleaf模板 <body > <!--Thymeleaf 前端框架以 Html 为载体--> <span th:text="${data}"></span> <span th:text="${data}"></span> <p th:text="${data}"></p> <div th:text="${data}"></div> </body> </html>
这样在thymeleaf模板中修改 内的标签在网页上也会相应的动态修改(不用重启项目程序)。
语法 ${...}
标准变量表达式用于访问容器(tomcat)上下文环境中的变量,功能和 EL 中的 ${} 相 同。Thymeleaf 中的变量表达式使用 ${变量名} 的方式获取 Controller 中 model 其中的数据。
例子:
user类
package com.example.model; public class user { private int num; private String name; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
UserController类:
package com.example.web; import com.example.model.user; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.jws.WebParam; @Controller public class UserController { @RequestMapping(value = "/user/detail") public String message(Model model) { user user = new user(); user.setName("KB"); user.setNum(24); model.addAttribute("user",user); return "message"; } }
message.html:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> PlayerNum :<div th:text="${user.getNum()}"> message showed:</div><br/> PlayerName:<div th:text="${user.getName()}"> message showed:</div> PlayerNum :<div th:text="${user.getNum()}"> message showed:</div><br/> PlayerName:<div th:text="${user.getName()}"> message showed:</div> </body> </html>
核心配置文件:
#设置themeleaf模板引擎的前后缀 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html #设置缓存 spring.thymeleaf.cache=false
结果:
PlayerNum :
24
PlayerName:
KB
PlayerNum :
24
PlayerName:
KB
语法:*{...}
说明:
示例:
<div th:Object="${user}"> PlayNum :<span th:text="*{getNum()}"></span><br/> PlayerName:<span th:text="*{getName()}"></span> </div>
其他类和上面一样。
标准变量和选择变量表达式可以混合使用,也可以不混合使用,使用 th:object 进行对 象的选择,也可以直接使用 *{...} 获取数据:
示例:
PlayerNum :<div th:text="*{user.getNum()}"> message showed:</div><br/> PlayerName:<div th:text="*{user.getName()}"> message showed:</div>
不带参数:
<h1>URL 路径表达式:@{...}</h1> <h2>绝对路径(没有参数)</h2> <a th:href="@{http://localhost:8080/thymeleaf/info}">查看:绝对路径</a>
带参数:
<h2>绝对路径(路径中有参数)</h2> <a th:href="@{'http://localhost:8080/thymeleaf/user/info?id=' + ${user.id}}">查看用户信息:绝对路径(带参数)</a>
不推荐使用:路径写死。
不带参数:
<h2 style="color: red">实际开发推荐使用:相对路径(没有参数)</h2> <a th:href="@{/thymeleaf/info}">查看:相对路径</a>
带参数:
:
user类:
package com.example.model; public class user { private int num; private String name; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
UserController类:
package com.example.web; import com.example.model.user; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.jws.WebParam; @Controller public class UserController { // public ModelAndView message( ) //// { //// user user = new user(); //// user.setNum(30); //// user.setName("SC"); //// ModelAndView modelAndView =new ModelAndView(); //// modelAndView.setViewName("userInfomation"); //// modelAndView.addObject("userNum",user.getNum()); //// modelAndView.addObject("userName",user.getName()); //// return modelAndView; //// } @RequestMapping(value = "/user/detail") public String message(Model model) { user user =new user(); user.setName("KB"); user.setNum(24); model.addAttribute("user",user); return "message"; } @RequestMapping(value = "/user/Info") public @ResponseBody String userInfo(int num,String name) { return "num:"+num+" Name:"+name; } }
message.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a th:href ="@{/user/Info(num=${user.getNum()},name=${user.getName()})}">click</a> </body> </html>
核心配置文件:
#设置themeleaf模板引擎的前后缀 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html #设置缓存 spring.thymeleaf.cache=false server.servlet.context-path=/url
设置请求方法
<form th:action="@{/user/login}" th:method="post"></form>
定义超链接,主要结合 URL 表达式,获取动态变量.
<a href="http://www.baidu.com">超链接百度</a><br/> <a th:href="'http://www.baidu.com?id=' + ${user.id}">th:href 链接</a>
用于外部资源引入,比如