Skip to content

GJW459/community

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

码匠社区

部署

资料

Spring文档
Spring web
Bootstrap
Github OAuth Document

工具

git
git init:创建仓库
git type:查看可以提交的文件
git add .全部加到缓存库里
git commit -m "提交"
git remote origin 和远程连接
git push 推向github
vp或者visio画时序图

所用知识

springboot
mybatis
bootstrap

步骤

实现GitHub登录 继承h2数据库

sql脚本
create table USER
(
  ID           INTEGER default NEXT VALUE FOR "PUBLIC"."SYSTEM_SEQUENCE_840EA468_2952_4804_885B_528E019C0F51"
    primary key,
  ACCOUNT_ID   VARCHAR(100),
  NAME         VARCHAR(50),
  TOKEN        VARCHAR(50),
  GMT_CREATE   BIGINT,
  GMT_MODIFIED BIGINT
  # 通过这个创建用户名和密码
  create user if not exists sa password '123';
    alter user sa admin true
);

第一个功能

实现GitHub的第三方登录

  1. 通过向GitHub获取权限,获取权限后调用GitHub的user接口, 通过okhttp返回一个json字符串再由fastjson将这个json字符串装换成GitHubUser对象这是一个数据传输对象 ,再通过在控制器里面将GitHubUser对象的属性封装到User对象中,最后存入MySql数据库
  2. Cookie和Session对象
  • 首先Cookie不是Servlet中的九大内置对象,需要实列化,session对象是内置对象不需要实列化
  • 从GitHub中获取到User对象存入数据库后,我们可以HttpServletResponse对象返回一个自定义Cookie对象给客户端
  • java Servlet API引入session 机制来跟踪客户的状态,session指的是在一段时间内,单个客户和web服务器之间一连串的交互过程,在一个session中,一个客户可能会多次请求同一个网页,也可能请求多个不同服务器资源,例如:在一个邮件系统应用中,从一个客户登录到邮件系统,到写信,收信和发信等,到最后退出邮件系统,整个过程为一个session;再例如:大家在网上购物的时候,从购物到最后的付款,整个过程也是一个session 。
  • session对像是jsp中的内置对象,可以直接使用;在Servlet中使用session时,必须先创建出该对象,Servlet中创建session的方法: HttpSession session=request.getSession();或 HttpSession session=request.getSession(boolean value); 在服务器上,通过session ID来区分每一个请求服务器的用户,用户只要一连接到服务器,服务器就会为之分配一个唯一的不会重复的session ID,session ID由服务器统一管理,人为不能控制 web容器关闭或重启,session会死亡调用session.invalidate();方法,强制session死亡 前后两次请求超过了session指定的生命周期时间,默认为30分钟
  • Cookie和Session的区别 session将信息保存在服务器上,cookie保存在客户端上 session比cookie更安全,session比cookie更占资源 session使用cookie的机制,如果cookie被禁用,那么session也无法使用,因为session ID是以cookie的形式保存在客户端的内存当中
  1. 通过本地Cookie实现自动登录
 Cookie[] cookies = request.getCookies();
        //获取所有的Cookie
        if (cookies!=null){
            for (Cookie cookie : cookies) {

                //key 为token的Cookie
                if (cookie.getName().equals("token")){

                    String token=cookie.getValue();
                    User user=userMapper.findByToken(token);
                    if (user!=null){
                        //向服务端传session对象
                        request.getSession().setAttribute("user",user);
                    }
                    break;
                }
            }
        }

初识flyway

第二个功能:发布问题

  • bootstrap 实现页面
  • controller 处理请求
  • thymeleaf 模板引擎渲染页面

初识lombok

lombok是一个插件:可以简化代码操作,通过注解生成get,set,toString,构造函数,hashcode方法

  • 优点:简化代码
  • 确定:不能实现多参构造,只能实现全参和无参,代码可读写差
  • 使用:IDEA下载lombok插件,maven引入lombok依赖 常见注解
  1. @Data:自动生成所有的get set方法
  2. @Getter/@Setter:自动生成get/set方法
  3. @NonNull:校验参数,能够防止空指针异常
  4. @Cleanup:自动调用close()方法,关闭流,常用来文件的读写
 @Cleanup InputStream in = new FileInputStream(args[0]);
 @Cleanup OutputStream out = new FileOutputStream("asdaads");
  • @ToString:生成 toString()方法
  • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor参数(Args)构造器(constructor)

实现分页功能

  • 此分页功能没有基于插件,是自己写逻辑实现
  • 分页步骤
  1. controller控制器接收请求,请求内包含page:页号,size:一页的list question数
  2. controller依赖于service层,通过将page和size传入service层的list方法返回一个实体类:这个List questions 和 User的一些信息,分页的一些信息
  3. service依赖于dao层:调用dao的方法获取List question
  4. service在通过PaginationDTO 的setPagination方法设置分页信息返回给controller层
//导航到首页 需要的属性
@Data
public class PaginationDTO {

    //QuestionDto : Question and User
    private List<QuestionDto> questionDtoList;

    //是否展示前一页
    private boolean showPrevious;
    //是否展示第一页
    private boolean showFirstPage;
    //是否展示下一页
    private boolean showNext;
    //是否展示最后一页
    private boolean showEndPage;
    //当前页
    private Integer currentPage;
    //页数数组:1,2,3,4,5
    private List<Integer> pages=new ArrayList<>();
    //总页数
    private Integer totalPage;

    public void setPagination(Integer totalCount,Integer page,Integer size){

        this.currentPage=page;

        //计算总共页数
        Integer totalPage;
        if (totalCount%size==0){
            totalPage=totalCount/size;
        }else {
            totalPage=totalCount/size+1;
        }
        this.totalPage=totalPage;

        if (page<0){
            page=1;
        }
        if (page>totalPage){
            page=totalPage;
        }

        //向列表插入页号
        //推导的逻辑
        pages.add(page);
        for (int i=1;i<=3;i++){
            //如果是第二页后
            if (page-i>0){
                //插在头部
                pages.add(0,page-i);
            }
            if (page+i<=totalPage){
                pages.add(page+i);
            }
        }
        //第一个判断什么时候有上一页
        if (page==1){
            showPrevious=false;//不显示
        }else {
            showPrevious=true;
        }
        //是否展示上一页 没有那个图标
        if (totalPage==page){
            showNext=false;
        }else {
            showNext=true;
        }

        //是否展示第一页
        if (pages.contains(1)){

            //当列表包含1时不展示
            showFirstPage=false;
        }else {
            showFirstPage=true;
        }
        //是否展示最后一页
        if (pages.contains(totalPage)){

            showEndPage=false;
        }else {
            showEndPage=true;
        }

    }
}

实现个人资料发布问题列表

  • 和分页功能相似

拦截器

  • 拦截器:拦截所有的请求,实际上是拦截请求所对应的handler
  • 过滤器:拦截请求 拦截器:拦截handler
  • springboot通过扩展spring mvc的组件功能
//扩展springboot 中的spring mvc自动配置类 并且不覆盖自动配置类
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private SessionIntercepter sessionIntercepter;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sessionIntercepter).addPathPatterns("/**");
    }
}
  • 扩展类中不能用@EnableWVC注解 使用后会使spring mvc的auto configuration失效
  • 拦截器实现需要实现HandlerInterceptor接口重写三个方法

实现问题详情功能

  1. 通过点击首页的问题列表的title跳转到个人问题详情页面
  2. 返回给页面一个QuestionDto:Question + User 来渲染页面
  3. 左边显示问题的信息 title description 创建时间 修改时间 浏览次数 作者 右边显示发起人的头像和name
  4. 然后添加一个编辑链接,当session域中的user存在且user.id==QuestionDto.creator时才显示这个编辑链接

修复登录功能

  • 之前每次登录都要向数据库插入数据,所有会出现很多相同的用户
  • 解决:先判断,通过accountId查询User,如果user不存在就插入数据库,如果user存在就更新User的信息,因为每次的token都不同所有需要更新token字段

实现注销功能

  • remove session中的user
  • 普通的来说只需要remove user就行了,但是我们这里设置了一个拦截器,所有请求都被拦截,拦截后先获取request域(客户端)中的所有Cookie,再遍历Cookie获取服务端响应给客户端的Token Cookie,然后在根据Token查询数据库中的User对象,往session域中再添加一个User,所以这里必须同时销毁Cookie
  • 消除Token为key的Cookie的方法
@Controller
public class AuthorizeController {

    //退出登录
    @GetMapping("/logout")
    public String logout(HttpServletRequest request,
                         HttpServletResponse response) {
        //删除session和cookie
        request.getSession().removeAttribute("user");
        //删除cookie只需要覆盖就行了
        Cookie cookie = new Cookie("token", null);
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        return "redirect:/";
    }
}

实现编辑功能

  1. 先点击编辑链接,然后被对应的handler所处理返回给publish.html当前编辑问题的所有信息,包括id
  2. 在publish.html中添加一个类型为hidden的 input标签
  3. 通过提交form表单进行doPublish,判断是create 还是 update 如果提交的id不为空,就update,反之insert

About

基于springboot,mybatis3,thymeleaf3.0的社区系统

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors