springboot demo(二)web开发demo

Posted on 2020-05-02 15:22  FLGB  阅读(716)  评论(0编辑  收藏  举报

如入门般建立项目,引入依赖:

<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。

两个步骤:

  1. 实现Filter接口,实现Filter方法

  2. 添加@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参数的作用主要用于:自动创建|更新|验证数据库表结构,有四个值:

  1. create: 每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。

  2. create-drop :每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。

  3. update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。

  4. validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。

dialect 主要是指定生成表名的存储引擎为InneoDB
show-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

 

Copyright © 2024 FLGB
Powered by .NET 8.0 on Kubernetes