zoukankan      html  css  js  c++  java
  • 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。

    两个步骤:

    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

  • 相关阅读:
    二叉树的前中后序遍历(非递归)
    剑指offer——圆圈中最后剩下的数字
    剑指offer——和为s的连续正整数序列
    leetcode300.最长上升子序列
    将网络描述符设置为非阻塞的场景
    leetcode72.编辑距离
    浅谈各种锁机制
    TCP如何保证可靠传输?
    JavaScript(七)
    JavaScript(六)
  • 原文地址:https://www.cnblogs.com/flgb/p/12818227.html
Copyright © 2011-2022 走看看