springboot demo(二)web开发demo
如入门般建立项目,引入依赖:
<dependencies>
<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>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
编写代码Controller:
@RestController
public class UserController { @RequestMapping("user/getUser")
public User getUserInfo() {
try {
User user = (User) ModelBuilders.bulid(User.class);
user.setUsername("朱XPHB明");
user.setPassword("AG8xph0b271");
user.setAddress("世纪汇广场");
return user;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
entity:使用了lombok
package springboot_webdemo.entity; import lombok.Getter;
import lombok.Setter; public class User { @Getter
@Setter
private String username; @Getter
@Setter
private String password; @Getter
@Setter
private String address;
}
bulider
public class ModelBuilders { public static Object bulid(Class clz) throws Exception, IllegalAccessException{ Object instance = clz.newInstance();
return instance;
} }
运行效果:自动返回json格式use信息数据
{"username":"朱XPHB明","password":"AG8xph0b271","address":"世纪汇广场"}
自定义Filter
我们常常在项目中会使用filters用于录调用日志、排除有XSS威胁的字符、执行权限验证等等。Spring Boot自动添加了OrderedCharacterEncodingFilter和HiddenHttpMethodFilter,并且我们可以自定义Filter。
两个步骤:
实现Filter接口,实现Filter方法
添加
@Configuration
注解,将自定义Filter加入过滤链
代码如下:
public class InterfaceCostFilter implements Filter{ @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
long benginTime = System.currentTimeMillis();
chain.doFilter(request, response);
long endTime = System.currentTimeMillis();
long cost = endTime - benginTime;
System.out.println("InterfaceCostFilter记录本次调用服务花费时间:"+cost+"ms");
} @Override
public void destroy() { } }
加入过滤器链
@Configuration
public class FilterConfig { //应用程序运行在一台负载均衡代理服务器后方,因此需要将代理服务器发来的请求包含的IP地址转换成真正的用户IP。
//Tomcat 8 提供了对应的过滤器:RemoteIpFilter
@Bean
public RemoteIpFilter remoteIpFilter(){
return new RemoteIpFilter();
} @Bean
public FilterRegistrationBean<Filter> getInterfaceCostFilter(){ FilterRegistrationBean registrationBean = new FilterRegistrationBean ();
registrationBean.setFilter(new InterfaceCostFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.addInitParameter("nickname", "王小二");//添加默认参数
registrationBean.setName("InterfaceCostFilter");
registrationBean.setOrder(1);
return registrationBean;
}
}
添加一个获取拦截器信息参数的Controller,registration可以拿到拦截器的信息
@RestController
public class FilterController { @Autowired
FilterRegistrationBean registration; @RequestMapping("filter/getFilterParam")
public Map<String,String> getUserInfo() {
try {
Map<String,String> map = registration.getInitParameters();
// Filter filter = registration.getFilter();
String nickname = (String) map.get("nickname");
return map;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
执行结果1:
InterfaceCostFilter记录本次调用服务花费时间:3ms
执行结果2:
InterfaceCostFilter记录本次调用服务花费时间:1ms
注解版filter实现
@WebFilter(urlPatterns="/*",filterName="InterfaceCostFilterByAnno",initParams={@WebInitParam(name="age",value="21"),
@WebInitParam(name = "charSet", value = "utf-8")})
public class InterfaceCostFilterByAnno implements Filter{ @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
long benginTime = System.currentTimeMillis();
chain.doFilter(request, response);
long endTime = System.currentTimeMillis();
long cost = endTime - benginTime;
System.out.println("InterfaceCostFilterByAnno记录本次调用"+"服务花费时间:"+cost+"ms");
} @Override
public void destroy() { } }
springboot启动类添加注解
@SpringBootApplication
@ServletComponentScan("springboot_webdemo.filter")
public class App { public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
} }
FilterConfig中添加@Primary
@Bean
@Primary
public FilterRegistrationBean<InterfaceCostFilter> getInterfaceCostFilter(){ FilterRegistrationBean registrationBean = new FilterRegistrationBean ();
registrationBean.setFilter(new InterfaceCostFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.addInitParameter("nickname", "王小二");//添加默认参数
registrationBean.setName("InterfaceCostFilter");
registrationBean.setOrder(1);
return registrationBean;
}
测试:
InterfaceCostFilterByAnno记录本次调用服务花费时间:3ms
InterfaceCostFilter记录本次调用服务花费时间:3ms
InterfaceCostFilterByAnno记录本次调用服务花费时间:2ms
InterfaceCostFilter记录本次调用服务花费时间:2ms
返回的是加@Primary的值
不建议使用注解
多个过滤器实现
@Configuration
public class FilterConfig { //应用程序运行在一台负载均衡代理服务器后方,因此需要将代理服务器发来的请求包含的IP地址转换成真正的用户IP。
//Tomcat 8 提供了对应的过滤器:RemoteIpFilter
@Bean
public RemoteIpFilter remoteIpFilter(){
return new RemoteIpFilter();
} @Bean
// @Primary
public FilterRegistrationBean<InterfaceCostFilter> getInterfaceCostFilter(){ FilterRegistrationBean registrationBean = new FilterRegistrationBean ();
registrationBean.setFilter(new InterfaceCostFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.addInitParameter("nickname", "王小二");//添加默认参数
registrationBean.setName("InterfaceCostFilter");
registrationBean.setOrder(2);
return registrationBean;
} @Bean
@Primary
public FilterRegistrationBean<Filter> interfaceCostFilterByAnno(){ FilterRegistrationBean registrationBean = new FilterRegistrationBean ();
registrationBean.setFilter(new InterfaceCostFilterByAnno());
registrationBean.addUrlPatterns("/*");
registrationBean.addInitParameter("nickname", "王小二");//添加默认参数
registrationBean.addInitParameter("age", "张三");//添加默认参数
registrationBean.setName("interfaceCostFilterByAnno");
registrationBean.setOrder(1);
return registrationBean;
}
多个过滤器先执行order小的,
@Primary注入FilterRegistrationBean的时候注入,也可以使用别名注入
日志添加
log配置
配置输出的地址和输出级别
logging.path=D:/user/local/log
logging.level.springboot_webdemo=DEBUG
logging.level.org.springframework.web=INFO
logging.level.org.hibernate=ERROR
path为本机的log地址,logging.level
后面可以根据包路径配置不同资源的log级别
代码中使用日志:lombok提供支持
@RestController
@Slf4j
public class UserController { @RequestMapping("user/getUser")
public User getUserInfo() {
try {
User user = (User)ModelBuilders.bulid(User.class);
user.setUsername("朱XPHB明");
user.setPassword("AG8xph0b271");
user.setAddress("世纪汇广场");
log.info("user={}",user.toString());
return user;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
运行访问:
20-05-02 17:14:29.269 INFO 8188 --- [nio-8080-exec-1] s.controller.UserController : user=User [username=朱XPHB明, password=AG8xph0b271, address=世纪汇广场]
@RestController@Slf4jpublic class UserController {@RequestMapping("user/getUser")public User getUserInfo() {try {User user = (User)ModelBuilders.bulid(User.class);user.setUsername("朱XPHB明");user.setPassword("AG8xph0b271");user.setAddress("世纪汇广场");log.info("user={}",user.toString());return user;} catch (Exception e) {e.printStackTrace();}return null;}}
自定义Property
在web开发的过程中,我经常需要自定义一些配置文件,如何使用呢
配置在application.properties中
com.lf.title=自定义属性
com.lf.description=自定义属性描述
代码中获取属性值
@Component
@Data
public class CommonProperties { @Value("${com.lf.title}")
private String title; @Value("${com.lf.description}")
private String description; }
Controller
@Slf4j
@RestController
public class PropertiesController { @Autowired
private CommonProperties commonProperties; @RequestMapping("/getProperties")
public CommonProperties getCommonProperties(){
log.info("commonProperties={}",commonProperties.getTitle());
return commonProperties;
}
}
访问:
关于读取配置乱码
java读properties文件的时候,只认识ascii码,如\u4e2d这种,不认识汉字 。
STS --https://blog.csdn.net/gjm15652957971/article/details/80311714
IDEA--
先修改properties文件的编码格式
修改为utf-8,同时去Idea里面修改properties编码设置:
Settings ——》Editor ——》 File Encodings
选择UTF-8,同时勾选Transparent native-to-ascii conversion,如下图
数据库操作
spring data jpa的使用
1、添加相jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2、添加配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
其实这个hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构,有四个值:
create: 每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop :每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
dialect
主要是指定生成表名的存储引擎为InneoDBshow-sql
是否打印出自动生产的SQL,方便调试的时候查看
3、添加实体类和Dao
改造原有User类
Entity中不映射成列的字段得加@Transient 注解,不加注解也会映射成列
@Table(name="lf_user")
@Entity
public class User implements Serializable{
@Id
@GeneratedValue
@Getter
@Setter
private Long id;
@Getter
@Setter
@Column(nullable = false, unique = true)
private String username; @Getter
@Setter
private String password; @Getter
@Setter
private String address;
dao只要继承JpaRepository
public interface UserRepository extends JpaRepository<User, Long> { User findByUsername(String username); User findByUsernameOrAddress(String username, String address); List<User> findAll();
}
service
@Service
public class UserService implements IUserService{ @Autowired
private UserRepository userRepository; @Override
public User findByUsername(String username) { return userRepository.findByUsername(username);
} @Override
public User findByUsernameOrAddress(String username, String address) { return userRepository.findByUsernameOrAddress(username, address);
} @Override
public List<User> findAll() {
return userRepository.findAll();
} }
controller
@RequestMapping("user/getAllUser")
public List<User> getAllUser() {
try {
List<User> userlist = userService.findAll();
log.info("user={}",userlist.size());
return userlist;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
4、测试
数据库中手动插入了两条数据,用findAlL方法成功查询返回。
代码链接:https://github.com/FLGBetter/springboot_webdemo
springboot demo(二)web开发demo的更多相关文章
- Spring入门(二):SpringBoot之基础Web开发
接上回 现在,我们已经能自行完成SpringBoot的初级项目搭建了,接下来看如何实现一些Web开发中的基础功能. 先看项目完整的目录结构: 1. 返回Json数据 创建model文件夹,并新建Per ...
- 浩顺AC671指纹考勤机二次开发(demo)
关于考勤机 AC671,是新换的机器,以前的那部机器,通过网络死活连接不上,换了AC671网络连接是好用了.但是,我要吐槽 浩顺的考勤机应该是卖了很多了吧,可是自带的软件太不给力,最后分析出来的数据一 ...
- SpringBoot起飞系列-Web开发(四)
一.前言 从今天你开始我们就开始进行我们的web开发,之前的一篇用SpringBoot起飞系列-使用idea搭建环境(二)已经说明了我们如何进行开发,当然这是搭建起步,接下来我们就开始进行详细的开发, ...
- Struts2技术内幕 读书笔记二 web开发的基本模式
最佳实践 在讨论基本模式之前,我们先说说一个词:最佳实践 任何程序的编写都得遵循一个特定的规范.这种规范有约定俗称的例如:包名全小写,类名每个单词第一个字母大写等等等等;另外还有一些需要我们严格遵守的 ...
- springboot核心技术(三)-----web开发
web开发 1.简介 使用SpringBoot: 1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运 ...
- 百度地图二次开发Demo
单点标注:电子显示对应位置的图片,信息框 多点标注(批量点标注): 多点连线(基于多个点形成路径): 若须要Demo源码:请给我发邮箱 1507026255@qq.com 转载请注明小刘
- Springboot学习:Web开发介绍
简介 使用SpringBoot: 1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来 3).自 ...
- 六十二 Web开发 使用模板
Web框架把我们从WSGI中拯救出来了.现在,我们只需要不断地编写函数,带上URL,就可以继续Web App的开发了. 但是,Web App不仅仅是处理逻辑,展示给用户的页面也非常重要.在函数中返回一 ...
- Spring基础系列-Web开发
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9996902.html SpringBoot基础系列-web开发 概述 web开发就是集成 ...
随机推荐
- innodb引擎的4大特性
一:插入缓冲 二:二次写 三:自适应哈希 四:预读 1.插入缓冲(insert buffer)插入缓冲(Insert Buffer/Change Buffer):提升插入性能,change buffe ...
- Java语法糖详解
语法糖 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更 ...
- tcpdump安装与参数详解
Centos7安装Tcpdump 对于大部分的Linux操作系统,已经默认安装了tcpdump,可以通过以下命令查看: [root@localhost local]# tcpdump --versio ...
- ShardingSphere内核原理 原创 鸽子 架构漫谈 2021-01-09
ShardingSphere内核原理 原创 鸽子 架构漫谈 2021-01-09
- loj10018数的划分
题目描述 将整数 n 分成 k 份,且每份不能为空,问有多少种不同的分法.当 n=7,k=3 时,下面三种分法被认为是相同的:1 1 5;1 5 1 ;5 1 1 输入格式 一行两个数 n ,k . ...
- 石子游戏(nim游戏+按位考虑)
题意 给\(n\)堆石子,每次最多可以从一堆中取\(x\)个,问你\(x = 1 ... n\)时的答案. 解法 经典\(nim\)游戏,找规律知\(sg[i] = i \ mod \ (x+1)\) ...
- 单机模拟配置Eureka集群
首先先提醒单机部署的重要点 如果使用一个ip地址(适用于单网卡)每个eureka实例使用不同的域名映射到同一个IP 如果每个eureka实例使用不同的IP(多网卡),要确保这些IP要都表示本地 本文假 ...
- cassandra权威指南读书笔记--配置cassadnra
配置集群时,要求所有节点的集群名,分区器,snitch必须相同.种子节点最好相同. 种子节点:最好每个DC,配置2个,这样即使一个DC中一个种子节点挂了,仍然有一个中子节点可用.种子节点被认为是最先加 ...
- Flink-v1.12官方网站翻译-P012-Stateful Stream Processing
有状态的流处理 什么是状态? 虽然数据流中的许多操作一次只看一个单独的事件(例如事件解析器),但有些操作会记住多个事件的信息(例如窗口操作符).这些操作被称为有状态操作.一些有状态操作的例子. - 当 ...
- Flink-v1.12官方网站翻译-P009-Event-driven Applications
事件驱动的应用 处理函数 简介 ProcessFunction将事件处理与定时器和状态结合起来,使其成为流处理应用的强大构件.这是用Flink创建事件驱动应用的基础.它与RichFlatMapFunc ...