community项目总结

看小匠的视频,跟着一路做下来,感觉收获了很多东西, 这里总结一下,不然过不久就忘了。

方法/思想/技巧

  1. 不要过度设计,很多东西用到再说。(只是不要过度,该设计还是要设计的,否则要改了常常牵一发而动全身)
  2. 要学一个东西,看官方文档是最有效的,这里的有效不是快,而是理解掌握,否则看别人的二手资料,cv,终究不是自己的。而且遇到什么参数、名词不理解,随时ctrl+f在文档里面找。也容易对这个技术形成一个整体的概念
  3. 搜索是有方法的,遇到问题不应该直接cv+post到搜索框去,或者加上自己的上下文,而是用 关键词+空格 的方式,更加快捷和全面

功能

一环扣一环,从最根本最需要的地方出发。发布问题功能就是一开始的“根”功能。

功能流程图

图片

功能模块

登陆接口

具体在下面

问题发布

图片

问题列表

给开始页码和页面大小,取数据库查,然后在index页面显示出来

分页功能

根据传进来的参数设置好开始页数、总页数、导航总页数、导航页数,是否是第一页等信息,再把从数据库查的分好页的list集合赋值给它,传给前端就是带有分页信息的数据了。(如question->questionDTO)

拦截器

不管怎么样最后都会return true放行,只不过如果是带着银行卡来的话,会给相应的银行账户一个属性user

@Service
public class SessionInterceptor implements HandlerInterceptor {
    @Autowired
    UserMapper userMapper;
    @Autowired
    NotificationServiceImpl notificationService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length != 0) {
            for (Cookie cookie : cookies
            ) {
                if (cookie.getName().equals("token")) {
                    String token = cookie.getValue();
                    QueryWrapper<User> queryWrapper = new QueryWrapper();
                    queryWrapper.eq("token", token);
                    List<User> users = userMapper.selectList(queryWrapper);
                    if (users.size() != 0) {
                        HttpSession session=request.getSession();
                        session.setAttribute("user",users.get(0));
                        int unreadCount = notificationService.unreadCount(users.get(0).getId());
                        session.setAttribute("unreadCount", unreadCount);
                    }
                    break;
                }
            }
        }
        return true;
    }

退出登陆

@GetMapping("/logout")
public String logout(
        HttpServletRequest request,
        HttpServletResponse response
){
    request.getSession().removeAttribute("user");
    Cookie cookie=new Cookie("token",null);
    cookie.setMaxAge(0);
    response.addCookie(cookie);
    return "redirect:/";
}

问题详情

带着诸多信息去就行了

问题更新

用到了GetMapping("/publish/{id}") return “publish”;

异常处理

异常处理

评论回复

这个评论回复涉及了三个对象,一个是评论的人,一个是被评论的人,还有一个是相关的 问题/评论。因为还有一个二级的评论,感觉就略复杂了一点。

相光问题

利用正则匹配标签找相关问题

优化标签

public class TagCache {
    public static List<TagDTO> get() {
        List<TagDTO> tagDTOS = new ArrayList<>();
        TagDTO program = new TagDTO();
        program.setCategoryName("开发语言");
        program.setTags(Arrays.asList("javascript", "php", "css", "html", "html5", "java", "node.js", "python", "c++", "c", "golang", "objective-c", "typescript", "shell", "swift", "c#", "sass", "ruby", "bash", "less", "asp.net", "lua", "scala", "coffeescript", "actionscript", "rust", "erlang", "perl"));
        tagDTOS.add(program);

        TagDTO framework = new TagDTO();
        framework.setCategoryName("平台框架");
        framework.setTags(Arrays.asList("laravel", "spring", "express", "django", "flask", "yii", "ruby-on-rails", "tornado", "koa", "struts"));
        tagDTOS.add(framework);


        TagDTO server = new TagDTO();
        server.setCategoryName("服务器");
        server.setTags(Arrays.asList("linux", "nginx", "docker", "apache", "ubuntu", "centos", "缓存 tomcat", "负载均衡", "unix", "hadoop", "windows-server"));
        tagDTOS.add(server);

        TagDTO db = new TagDTO();
        db.setCategoryName("数据库");
        db.setTags(Arrays.asList("mysql", "redis", "mongodb", "sql", "oracle", "nosql memcached", "sqlserver", "postgresql", "sqlite"));
        tagDTOS.add(db);

        TagDTO tool = new TagDTO();
        tool.setCategoryName("开发工具");
        tool.setTags(Arrays.asList("git", "github", "visual-studio-code", "vim", "sublime-text", "xcode intellij-idea", "eclipse", "maven", "ide", "svn", "visual-studio", "atom emacs", "textmate", "hg"));
        tagDTOS.add(tool);
        return tagDTOS;
    }
}

我的问题

@Controller
public class ProfileController {
    @Autowired
    QuestionServiceImpl questionService;
    @Autowired
    NotificationServiceImpl notificationService;

    @GetMapping("/profile/{action}")
    public String profile(@PathVariable("action")String action, Model model,
                          @RequestParam(name = "page", defaultValue = "1") Integer page,
                          @RequestParam(name = "size", defaultValue = "5") Integer size,
                          HttpServletRequest request
    ){
        User user = (User) request.getSession().getAttribute("user");
        if ("questions".equals(action)){
            model.addAttribute("section","questions");
            model.addAttribute("sectionName","我的问题");
            PaginationDTO pageInfo=questionService.selectList(user.getId(),page,size);
            model.addAttribute("pageInfo",pageInfo);
        }
        else if("replies".equals(action)){
            model.addAttribute("section","replies");
            model.addAttribute("sectionName","最新回复");
            PaginationDTO pageInfo=notificationService.selectList(user.getId(),page,size);
            model.addAttribute("pageInfo",pageInfo);
        }

        return "profile";
    }
}

通知功能

图片

通知功能和评论功能涉及到的东西都比较多。

markdown功能

开源markdown编辑器

根据它的教程配置文件就可以用了,主要是html支持markdown,还有markdown转html,支持图片上传。

可拓展功能

  • 搜索功能

这个因为想学了ElasticSerach再做这个功能,所以并没有实现搜索功能

  • 个人信息

进入个人页面之后可以修改简介之类的

  • 热门话题

根据浏览数回复数高的,展示在首页的右端

后端

HttpServletRequest request

  • 它的对象是request
    • HttpServletResponse同理
  • request对象中封装了什么信息?
    • HTTP的请求协议的全部内容,被自动封装到了request对象当中。 所以面向request接口可以获取请求协议中的所有信息。
  • request对象生命周期是多久?
    • 一次请求对应一个request对象。浏览器向服务器发送了一个URL,就会对应一次请求。

github登陆接口

图片

图是小匠的。

流程:

  1. 用户点击登陆
  2. 客户端发送请求,调用github授权
  3. github返回callback,带着code
  4. 客户端再发送请求,带着code,换得accesstoken
  5. github返回accesstoken
  6. 客户端再发送请求,带着accesstoken,得到用户信息
  7. 给用户登陆成功/失败

github oauth

掌握了一个,其他的看官方文档,也是大同小异的qq api

dto 数据传输层

  1. 方法如果需要两个以上的参数,可以把参数封装成一个dto类,用这个dto来传输
  2. 数据库尽量不使用外键,会降低检索的一个效率。如果需要用到另一个表的数据,可以用一个dto来装。

其实有些困惑:1.感觉这样子会很麻烦;2.这样子uml图之类的感觉会很难画啊

@Data
public class Question {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String title;
    private String description;
    private String tag;
    private Long gmtCreate;
    private Long gmtModified;
    private Long creator;
    private Long viewCount;
    private Long likeCount;
    private Long commentCount;
}

如上,question其实是不需要有user这个属性的。但是我们需要用,可以用questionDTO,把user放进去

@Data
public class QuestionDTO {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String title;
    private String description;
    private String tag;
    private Long gmtCreate;
    private Long gmtModified;
    private Long creator;
    private Long viewCount;
    private Long likeCount;
    private Long commentCount;
    private User user;
}

枚举

以前其实不是很清楚枚举要怎么用的。现在明白了:

  1. 用枚举类型来限制参数,只能从里面选,就降低了出错的可能
  2. 增加可扩展性
  3. 便于别人理解阅读
  4. 而且它里面也可以有属于自己的方法
public enum CommentTypeEnum {
    QUESTION(1),
    COMMENT(2);
    private Integer type;

    public Integer getType() {
        return type;
    }

    CommentTypeEnum(Integer type) {
        this.type = type;
    }

    public static boolean isExist(Integer type) {
        for (CommentTypeEnum commentTypeEnum : CommentTypeEnum.values()) {
            if (commentTypeEnum.getType() == type) {
                return true;
            }
        }
        return false;
    }
}

session和cookie

地址

代码生成器

地址

pageHelper

地址

flyway

地址

git

常用git指令

springboot配置文件和常用注释

地址

mybatis plus 条件构造器

官网

okHttp

配置

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.14.1</version>
</dependency>

使用

stream流

菜鸟教程

List<QuestionDTO> questionDTOS = questions.stream().map(q -> {
    QuestionDTO questionDTO = new QuestionDTO();
    BeanUtils.copyProperties(q, questionDTO);
    return questionDTO;
}).collect(Collectors.toList());

前端

  1. 在js代码加上debugger可以调试
  2. 可以在页面调好样式,然后复制到css文件来

图片

  1. ajax
  • 属性:contentType,默认值: “application/x-www-form-urlencoded”。

发送信息至服务器时内容编码类型

  • dataType 预期服务器返回的数据类型
  • 发给服务器的一般都是字符串,所以一般用json.tostringify字符串化data
$.ajax({
    type: "POST",
    url: "/comment",
    contentType: 'application/json',
    data: JSON.stringify({
        "parentId": targetId,
        "content": content,
        "type": type
    }),
    success: function (response) {
        if (response.code == 200) {
            // window.location.reload();
            parent.location.reload();
        } else {
            if (response.code == 2003) {
                let isAccepted = confirm(response.message);
                if (isAccepted) {
                    window.open("https://github.com/login/oauth/authorize?client_id=c05a2ccc4a4995c1b2e2&redirect_uri=http://localhost:8080/callback&scope=user&state=1");
                    localStorage.setItem("closable","true");
                    localStorage.getItem("closable")
                }
            } else {
                alert(response.message);
            }
        }
    },
    dataType: "json"
}

其他

  • List strings = Arrays.asList(“abc”, “”, “bc”, “efg”, “abcd”,"", “jkl”);
  • BeanUtils.copyProperties(user,userdto)

一个bean 属性到另一个bean,同一个类是不行的

  • JSON.parseObject 和 JSON.toJSONString
    • JSON.parseObject(string,person.class) 将json字符串转换为对象
      {“name”:“dawang”} 转化为person类,有name属性
    • JSON.toJSONString 对象转化为json字符串

需要有依赖。

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.58</version>
</dependency>
发布了14 篇原创文章 · 获赞 0 · 访问量 37

猜你喜欢

转载自blog.csdn.net/weixin_43559860/article/details/105018460
今日推荐