zoukankan      html  css  js  c++  java
  • 一个项目的记录:多人博客

    笔记

    Maven项目

    1. 从官网复制一份pom.xml
    2. 更改 maven mirror :
    • ~/.m2.setting.xml 影响全局
    • pom.xml 仅影响当前项目
    1. 按着官方文档创建一个Controller,一个Application
    2. 运行,成功。

    依赖注入

    Springboot推荐注解:官方文档

    Spring Boot favors Java-based configuration. Although it is possible to use SpringApplication with XML sources, we generally recommend that your primary source be a single @Configuration class. Usually the class that defines the main method is a good candidate as the primary @Configuration.

    1. 从XML配置加载Bean

    创建 src/main/resources/applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- <context:component-scan base-package="com.in28minutes.spring.basics"/> -->
        <bean id="" class=""></bean>
    </beans>
    

    创建 configuration/XmlConfiguration.java

    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    @Configuration
    @ImportResource({"classpath*:applicationContext.xml"})
    public class XmlConfiguration {
    }
    

    这样就大功告成了。但是xml方式是个古老的方式。。

    2. 从Java配置加载Bean

    创建 configuration/JavaConfiguration.java

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    @Configuration
    public class JavaConfiguration {
    	@Bean
    	public String someDummyBean1() {
    		return "someDummyBean1";
    	}
    }
    

    3. 自动装配

    @Inject注解,需要引入javax.inject

    一个小知识,记下来。转载于: @Autowired,@Inject,@Resource的区别:
    1、@Autowired是spring自带的,@Inject是JSR330规范实现的
    2、@Autowired、@Inject用法基本一样,不同的是@Autowired有一个request属性

    连接数据库

    Docker:-> MySQL
    ORM:Object Relationship Mapping 对象关系映射 -> MyBatis

    JPA:一个不需要写SQL的ORM框架?打个笔记,有时间专门看看。。。

    参考的官方文档:mybatis-spring-boot-autoconfigure

    创建 mapper/CityMapper.java

    @Mapper
    public interface CityMapper {
      @Select("SELECT * FROM CITY WHERE state = #{state}")
      City findByState(@Param("state") String state);
    }
    

    然后通过构造器注入mapper,但是发现还需要一个DataSource。
    所以: 参考官方文档:Working with SQL Databases

    MVC

    Model View Controller

    開始根據前端接口写模块

    吭哧吭哧。。。。

    security -> Springboot:Securing a Web Application

    官方文档:保护Web应用程序

    本指南将引导您完成使用受Spring Security保护的资源创建简单的Web应用程序的过程。

    引入 pom.xml:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    

    在configuration包里创建一个类:

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    }
    

    现在所有请求都被拦截了。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	http
    		.authorizeRequests()
    			.antMatchers("/", "/home").permitAll()
    			.anyRequest().authenticated()
    }
    

    这样又能访问了,但是有些还是不能。。。

    Request URL: http://...
    Request Method: POST
    Status Code: 403 
    

    查了一些资料。然后发现了一个叫csrf的东西。

    http.csrf().disable();
    

    这时候就可以访问了。

    Springboot antMatchers:
    匹配url遵循如下规则:
    ? matches one character(匹配一个字符)
    * matches zero or more characters(匹配0个或多个字符)
    ** matches zero or more directories in a path(匹配0个或多个目录)
    {spring:[a-z]+}} matches the regexp [a-z]+ as a path variable named "spring",意思是将使用[a-z]+ 正则去匹配spring的变量值

    继续加入:

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
    	UserDetails user =
    		 User.withDefaultPasswordEncoder()
    			.username("user")
    			.password("password")
    			.roles("USER")
    			.build();
    	return new InMemoryUserDetailsManager(user);
    }
    

    这里发现withDefaultPasswordEncoder() 方法被废弃掉了。看了源代码的注释看到它是不安全的。

    Using this method is not considered safe for production, but is acceptable for demos and getting started.

    Auth:

    1. Authentication:鉴权。-> 是不是?
    2. Authorization:验权。-> 有没有权限?

    登陆状态维持

    Cookie:
    Cookie 是一些数据, 存储于你电脑上的文本文件中。
    当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。
    Cookie 的作用就是用于解决 "如何记录客户端的用户信息"

    参考文档:JavaScript Cookie | 菜鸟教程

    记录一个权威的文档:rfc cookie

    SecurityContextHolder.getContext() 
    // 把用户信息(Cookie)保存在一个地方
    

    登陆 / 注册

    pass

    查看约束信息:show create table #{表名};

    登出(logout)

    参考1: spring-security-logout
    参考2: docs.spring.io/spring-security

    测试

                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.6.0</version>
                    <executions>
                        <execution>
                            <id>start-test-database</id>
                            <phase>pre-integration-test</phase>
                            <goals>
                                <goal>exec</goal>
                            </goals>
                            <configuration>
                                <longModulepath>false</longModulepath>
                                <executable>docker</executable>
                                <arguments>
                                    <argument>run</argument>
                                    <argument>--name</argument>
                                    <argument>test-mysql</argument>
                                    <argument>-e</argument>
                                    <argument>MYSQL_ROOT_PASSWORD=123456</argument>
                                    <argument>-e</argument>
                                    <argument>MYSQL_DATABASE=springboot</argument>
                                    <argument>-p</argument>
                                    <argument>3307:3306</argument>
                                    <argument>-d</argument>
                                    <argument>mysql</argument>
                                </arguments>
                            </configuration>
                        </execution>
                        <execution>
                            <id>teardown-test-database</id>
                            <phase>post-integration-test</phase>
                            <goals>
                                <goal>exec</goal>
                            </goals>
                            <configuration>
                                <longModulepath>false</longModulepath>
                                <executable>docker</executable>
                                <arguments>
                                    <argument>rm</argument>
                                    <argument>-f</argument>
                                    <argument>test-mysql</argument>
                                </arguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
    

    集成测试 和 销毁测试数据库

    运行:>mvn pre-integration-test
    销毁:>mvn post-integration-test

    Jenkins

    docker run -p 8080:8080 -v E:docker:/var/jenkins_home jenkins
    

    补剩下的笔记。。。

    • Controller 参数验证,清洗
    • Service 处理业务需求
    • Dao 访问数据库

    MyBatis参考文档
    MyBatis Getting Started

    记录问题

    遇到前端数据传不过来的问题:

    正确返回的response:{"status":"ok","msg":"登陆成功","data":{"id":1,"name":"张三","avatar":"","createdAt":"2020-02-19T05:35:34.331Z","updatedAt":"2020-02-19T05:35:34.331Z"},"login":true}

    错误返回的response:{"status":"ok","msg":"登陆成功","login":true}

    解决方法:data的getter忘了写。

    登陆时返回404

    返回的response:{"timestamp":"2020-02-19T05:39:22.740+0000","status":404,"error":"Not Found","message":"No message available","path":"/auth/login"}

    解决方法:给方法加上@ResponseBody

    使用错误的账号登陆时返回403

    返回的response:{"timestamp":"2020-02-19T05:41:18.728+0000","status":403,"error":"Forbidden","message":"Access Denied","path":"/auth/login"}

    正确返回的response:{"status":"fail","msg":"用户不存在","data":null,"login":false}

    解决方法:UserDetailsService接口抛出UsernameNotFoundException。

    java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

    解决方法:使用 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
    绝对不可以使用明文密码。

      1. 必须加密
      1. 加密是不可逆的
      1. 加密必须是一致的

    WARNING:不要自己设计加密算法

    created_at和updated_at两个字段不断的刷新,并且和数据库对不上

    原因:驼峰形式和下划线形式匹配不上
    解决方法:application.properties 加上 mybatis.configuration.mapUnderscoreToCamelCase=true

    Bean循环依赖问题

    Description:
    The dependencies of some of the beans in the application context form a cycle:
    ┌─────┐
    |  webSecurityConfig defined in file [.../WebSecurityConfig.class]
    ↑     ↓
    |  userService defined in file [.../UserService.class]
    └─────┘
    

    解决方法:我这里把一个Bean变成字段注入。。。了。。。

    避免某些字段序列化到前端(例如:密码)

    解决方法:Spring默认的序列化工具是jackson。查了资料:jackson not serelize得知@JsonIgnore注解可以解决

    maven-surefire-plugin报告 Tests run:0, Failure:0, Error:0, Skipped:0

    相关:Gradle 5 JUnit BOM and Spring Boot Incorrect Versions
    解决方式:pom.xml添加

    <properties>
        <junit-jupiter.version>5.6.0</junit-jupiter.version>
    </properties>
    

    集成测试:A type incompatibility occurred while executing org.codehaus.mojo:exec-maven-plugin:1.6.0:exec: java.lang.String cannot be cast to org.codehaus.mojo.exec.Modulepath

    解决方法: 中加入:

    <longModulepath>false</longModulepath>
    

    重构

    DRY原则:Don’t Repeat Yourself

    解决:重构了部分重复代码。。。(写了一个静态工厂方法)

    自动化测试

    测试驱动开发 TDD:Test-Driven Development

    为什么?

    1. 自动
    2. 节省时间
    3. 人会犯错
    4. 测试水平

    单元测试:unit test

    用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作

    • 黑盒测试

    集成测试:intergration test

    将部分代码集成一块进行测试

    冒烟测试:smoke test

    测试软件的基本功能

    回归测试:regression test

    重复以前的全部或部分的相同测试

  • 相关阅读:
    linux下安装字体解决爬虫截图乱码问题
    开线程爬取黑猫里的阿里投诉信息
    CSS以及JS各种库的在线CDN引用地址
    linux系统下安装PHP扩展pcntl
    linux系统下安装Git
    linux进行文件vim编辑时没有退出文件直接关闭出现E325: ATTENTION Found a swap file by the name "/usr/local/php/etc/.php.ini.swp"
    windows安装redis和PHP redis扩展
    找回phpstorm删除文件/文件夹(phpstorm删除文件/文件夹的恢复)
    YII报错笔记:<pre>PHP Notice &#039;yiiaseErrorException&#039; with message &#039;Uninitialized string offset: 0&#039; in /my/test/project/iot/vendor/yiisoft/yii2/base/Model.php:778
    linux下使用svn创建版本库和权限管理
  • 原文地址:https://www.cnblogs.com/pipemm/p/12327559.html
Copyright © 2011-2022 走看看