Java-中软-11 springboot——评论&关于我&搜索&推荐新闻&拦截器&权限管理

评论
实体类Comment
一条新闻可有多条评论
可对评论进行评论,parentComment为某条评论的上一级评论

@Entity
@Table(name = "t_comment")
public class Comment {
    @Id
    @GeneratedValue
    private Long id;
    private String nickname;
    private String email;
    private String content;
    private String avatar;
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;
    @ManyToOne
    private News news;
    @OneToMany(mappedBy = "parentComment")
    private List<Comment> replyComments = new ArrayList<>();
    @ManyToOne
    private Comment parentComment;
    private boolean adminComment;
    public Comment() {
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getAvatar() {
        return avatar;
    }
    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public List<Comment> getReplyComments() {
        return replyComments;
    }
    public void setReplyComments(List<Comment> replyComments) {
        this.replyComments = replyComments;
    }
    public Comment getParentComment() {
        return parentComment;
    }
    public void setParentComment(Comment parentComment) {
        this.parentComment = parentComment;
    }
    public boolean isAdminComment() {
        return adminComment;
    }
    public void setAdminComment(boolean adminComment) {
        this.adminComment = adminComment;
    }
    public News getNews() {
        return news;
    }
    public void setNews(News news) {
        this.news = news;
    }
    @Override
    public String toString() {
        return "Comment{" +
                "id=" + id +
                ", nickname='" + nickname + '\'' +
                ", email='" + email + '\'' +
                ", content='" + content + '\'' +
                ", avatar='" + avatar + '\'' +
                ", createTime=" + createTime +
                ", news=" + news +
                ", replyComments=" + replyComments +
                ", parentComment=" + parentComment +
                ", adminComment=" + adminComment +
                '}';
    }
}

dao层
在dao中,创建继承JpaRepository类的CommentDao接口
在CommentDao接口中,声明findByNewsIdAndParentCommentNull方法

public interface CommentDao extends JpaRepository<Comment,Long> {
    List<Comment> findByNewsIdAndParentCommentNull(Long newsId, Sort sort);
}

service层
(1)在service下,创建CommentService接口,声明save方法、findCommentByNewsId方法

public interface CommentService {
    void save(Comment comment);
    List<Comment> findCommentByNewsId(Long newsId);
}

(2)在service下的impl中,创建CommentServiceImpl类实现CommentService接口中声明的方法
save方法:判断评论有无上一级评论,若无,将comment的parentComment属性置为空;
调用commentDao的save方法,保存评论
findCommentByNewsId方法:根据创建时间排序,根据传入的newsId查找对应的comment,得到评论列表

@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private CommentDao commentDao;
    @Override
    public void save(Comment comment) {
        if(comment.getParentComment().getId()==-1){
            comment.setParentComment(null);
        }
        commentDao.save(comment);
    }
    @Override
    public List<Comment> findCommentByNewsId(Long newsId) {
        Sort sort = Sort.by("createTime");
        List<Comment> comments=commentDao.findByNewsIdAndParentCommentNull(newsId,sort);
        return comments;
    }
}

controller层
(1)在controller下的IndexController类中,创建news方法,实现到详情页面的跳转

    @RequestMapping("/news/{id}")
    public String news(@PathVariable Long id,Model model){
        News news = newsServcie.findNewsById(id);
        model.addAttribute("news",news);
        return "news";
    }

(2)在controller下,创建CommentController类,在CommentController类中
创建save方法:
1.从session中取user:若user为空,则为普通用户登录后评论;否则为管理员登录后评论
2.调用 commentService的save方法,保存评论
3.先调用comment的getNews()方法,得到当前评论对应的news
再调用news的getId方法,得到对应news的id
4.重定向,执行comment查询,刷新界面
创建comment方法:
1.根据传入的newsId,调用commentService的findCommentByNewsId方法,得到newsId对应的评论列表
2.将相关信息通过model传到前台

@Controller
public class CommentController {
    @Autowired
    private CommentService commentService;
    @PostMapping("/comments")
    public String save(Comment comment, HttpSession session){
        User user = (User) session.getAttribute("user");
        if(user==null){
            comment.setAdminComment(false);
        }else {
            comment.setAdminComment(true);
        }
        commentService.save(comment);
        Long newsId=comment.getNews().getId();
        return "redirect:/comments/"+newsId;
    }
    @RequestMapping("/comments/{newsId}")
    public String comments(@PathVariable Long newsId, Model model){
        List<Comment> comments=commentService.findCommentByNewsId(newsId);
        model.addAttribute("comments",comments);
        return "news :: commentList";
    }
}

运行结果
管理员登录后评论
在这里插入图片描述
评论成功
在这里插入图片描述

关于我
在controller下的IndexController类中,创建about方法,实现到about页面的跳转

    @RequestMapping("/about")
    public String about(){
        return "about";
    }

在这里插入图片描述

搜索
dao层
(1)在dao下的NewsDao接口中,创建findByquery方法,根据传入的参数,对标题、内容字段进行模糊查询

    @Query("select n from News n where n.title like ?1 or n.content like ?1")
    Page<News> findByquery(String s, Pageable pageable);

service层
(1)在service下的NewsService接口,声明findNewsByQuery方法

    Page<News> findNewsByQuery(String query, Pageable pageable);

(2)在service下的impl中,实现NewsService接口中声明的findNewsByQuery方法:
根据传入的query字符串、pageable参数,调用newsDao的findByquery方法,进行模糊查询

    @Override
    public Page<News> findNewsByQuery(String query, Pageable pageable) {
        return newsDao.findByquery("%"+query+"%",pageable);
    }

controller层
在controller下的IndexController类中,创建search方法,实现到搜索页面的跳转:
使用内置的Pageable来实现分页,将news,按news的更新时间进行降序排列,再取前3条news;
调用newsServcie的findNewsByQuery方法,进行模糊查询,得到对应新闻页面
将相关信息通过model传到前台

    @RequestMapping("/search")
    public String search(@PageableDefault(size = 3,sort = {"updateTime"},direction = Sort.Direction.DESC)Pageable pageable,String query,Model model){
        Page<News> page=newsServcie.findNewsByQuery(query,pageable);
        model.addAttribute("page",page);
        model.addAttribute("query",query);
        return "search";
    }

运行结果
搜索标题或内容含有2的新闻
在这里插入图片描述
下一页
在这里插入图片描述

推荐新闻
dao层
(1)在dao下的NewsDao接口中,创建findTop方法,查找前n条推荐新闻

    @Query("select n from News n where n.recommend=true")
    List<News> findTop(Pageable pageable);

service层
(1)在service下的NewsService接口,声明findTop方法

    List<News> findTop(int i);

(2)在service下的impl中,实现NewsService接口中声明的findTop方法:
将新闻按更新时间进行降序排列,再调用newsDao的findTop方法取前n条推荐新闻

    @Override
    public List<News> findTop(int i) {
        Sort sort= Sort.by(Sort.Direction.DESC,"updateTime");
        Pageable pageable = PageRequest.of(0, i, sort);
        return newsDao.findTop(pageable);
    }

controller层
在controller下的IndexController类中,创建lastestNews方法,得到最新推荐新闻,实现界面跳转:
调用newsServcie的findTop方法,显示推荐新闻前三条
将相关信息通过model传到前台

    @RequestMapping("/footer/lastestNews")
    public String lastestNews(Model model){
        List<News> lastestNewsList=newsServcie.findTop(3);
        model.addAttribute("lastestNewsList",lastestNewsList);
        return "_fragments :: lastestNewsList1";
    }

运行结果
在这里插入图片描述

拦截器
在这里插入图片描述
创建interceptor包,然后在其中创建LoginInterceptor类、WebConfig类
LoginInterceptor
从session中取user:若user为空,则说明没有登录,跳转到登录界面

public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(request.getSession().getAttribute("user") == null){
            response.sendRedirect("/admin");
            return false;
        }
        return true;
    }
}

WebConfig
配置文件:配置拦截器
拦截admin下所有请求
除了用于登录的/admin与/admin/login请求

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin")
                .excludePathPatterns("/admin/login");
    }
}

权限管理
实体类Role

@Entity
@Table(name = "t_role")
public class Role implements Serializable {
    private static final long serialVersionUID = 594829320797158219L;
    @Id
    private String id;
    private String name;
    private String description;
    //角色与用户   多对多
    @ManyToMany(mappedBy="roles")
    private Set<User> users = new HashSet<User>(0);
    //角色与权限  多对多
    @ManyToMany(fetch = FetchType.EAGER)
    private Set<Permission> permissions = new HashSet<Permission>(0);
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Set<User> getUsers() {
        return users;
    }
    public void setUsers(Set<User> users) {
        this.users = users;
    }
    public Set<Permission> getPermissions() {
        return permissions;
    }
    public void setPermissions(Set<Permission> permissions) {
        this.permissions = permissions;
    }
}

实体类Permission

@Entity
@Table(name = "t_permission")
public class Permission implements Serializable {
    private static final long serialVersionUID = -4990810027542971546L;
    /**
     * 主键
     */
    @Id
    private String id;
    private String name;
    private String code;
    private String description;
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}

数据库设计
t_permission
在这里插入图片描述
t_role
在这里插入图片描述
t_role_permissions

在这里插入图片描述
t_user_roles
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值