ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端页面的开发

来源:互联网 发布:怎么练淘宝模特动作 编辑:程序博客网 时间:2024/06/04 19:29

ssm(springmvc4+spring4+mybatis3)整合实战-个人博客系统-前端首页的开发

    前面介绍完了util包的各种工具类、service层、model层以及dao层的实现,可以说是分享了一大半了!可能有些博友对于其中的code的作用不是很知晓,但是我相信随着我controller以及页面的开发分享,我想,你会逐渐知晓前面介绍的作用的。特别是比较实用的各种工具类:比如日期处理、加密解密、web文件如图片等的处理、文件下载等等、分页工具类、异步或者同步response工具类等等。

    本篇博文将介绍介绍前端页面的开发。主要有首页的列表展示、首页分页与分类查询、首页数据的全文检索查询、博客详情、博客评论以及源代码或者叫文件下载

    1、首页请求/index可以得到首页,请求/downloadFile可以得到本博客系统的源码压缩包,控制器代码IndexController.java,其中首页博客列表展示时采用了缩略图的形式:这里面采用的技术是jsoup,去检索出博客内容中前三张图片,进行展示

package com.steadyjack.controller;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;import com.steadyjack.entity.Blog;import com.steadyjack.entity.PageBean;import com.steadyjack.service.BlogService;import com.steadyjack.util.PageUtil;import com.steadyjack.util.StringUtil;import com.steadyjack.util.WebFileUtil;/** * title:IndexController.java * description:前端主页Controller * time:2017年1月21日 下午10:28:50 * author:debug-steadyjack */@Controllerpublic class IndexController {@Resourceprivate BlogService blogService;@RequestMapping("/")public String defaultPage(){return "redirect:/index";}/** * title:IndexController.java * description:请求主页 * time:2017年1月21日 下午10:30:17 * author:debug-steadyjack * @param page * @param typeId * @param releaseDateStr * @param request * @return * @throws Exception */@RequestMapping("/index")public ModelAndView index(@RequestParam(value="page",required=false)String page,@RequestParam(value="typeId",required=false)String typeId,@RequestParam(value="releaseDateStr",required=false)String releaseDateStr,HttpServletRequest request)throws Exception{ModelAndView mav=new ModelAndView();if(StringUtil.isEmpty(page)){page="1";}Integer pageNo=Integer.parseInt(page);PageBean pageBean=new PageBean(pageNo,10);Map<String,Object> map=new HashMap<String,Object>();map.put("start", pageBean.getStart());map.put("size", pageBean.getPageSize());map.put("typeId", typeId);map.put("releaseDateStr", releaseDateStr);List<Blog> blogList=blogService.list(map);for(Blog blog:blogList){//用于存放博客内容里面的图片,从而生成缩略图-用于前端页面展示List<String> imagesList=blog.getImagesList();String blogInfo=blog.getContent();Document doc=Jsoup.parse(blogInfo);//查找扩展名是jpg的图片:根据页面需要拿n张图片,这里拿了3张Elements jpgs=doc.select("img[src$=.jpg]"); if (jpgs!=null && jpgs.size()>0) {for(int i=0;i<jpgs.size();i++){Element jpg=jpgs.get(i);imagesList.add(jpg.toString());if(i==2){break;}}}}mav.addObject("blogList", blogList);//查询参数StringBuffer param=new StringBuffer(); if(StringUtil.isNotEmpty(typeId)){param.append("typeId="+typeId+"&");}if(StringUtil.isNotEmpty(releaseDateStr)){param.append("releaseDateStr="+releaseDateStr+"&");}Long totalRecord=blogService.getTotal(map);Integer pageSize=10;String genPagination=PageUtil.genPagination(request.getContextPath()+"/index.html",totalRecord,pageNo,pageSize,param.toString());//分页、主页、页面title、跳转的页面地址  mav.addObject("pageCode",genPagination);mav.addObject("mainPage", "foreground/blog/list.jsp");mav.addObject("pageTitle","Java开源博客系统");mav.setViewName("mainTemp");return mav;}/** * title:IndexController.java * description:系统功能介绍页面 * time:2017年1月22日 下午8:48:10 * author:debug-steadyjack * @return * @throws Exception */@RequestMapping("/download")public ModelAndView download()throws Exception{ModelAndView mav=new ModelAndView();mav.addObject("mainPage", "foreground/system/download.jsp");mav.addObject("pageTitle","本站源码下载页面_Java开源博客系统");mav.setViewName("mainTemp");return mav;}/** * title:IndexController.java * description:下载系统源码 * time:2017年1月22日 下午9:56:12 * author:debug-steadyjack * @param request * @throws Exception */@RequestMapping("/downloadFile")public void downloadFile(@RequestParam(value="fileUrl")String fileUrl,@RequestParam(value="fileName")String fileName,HttpServletRequest request,HttpServletResponse response)throws Exception{WebFileUtil.downloadFile(request, response, fileUrl, fileName);}}
    其实,这个控制器controller就已经展示了springmvc的角色,彻底对springmvc的工作原理进行淋漓尽致的应用。看过springmvc的宏观工作原理的博友都知道,springmvc的工作原理大概是这样的:

1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet.2、DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。3、DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。4、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。5、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。6、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端

   看完之后,是不是觉得我的那个controller确实表示的淋漓尽致。只不过,现在自己写的时候,可以对上面的写法进行诸多优化,而且随着spring4.3还是4.2起对于controller的写法更加简洁了。

   比如对于请求参数的写法,可以用参数封装(当然啦,这个可能不是spring4.x的功能),controller返回的一般是String,即一个视图的地址等等。

   对于springmvc的详细介绍可以另外看多几篇博客。

   2、完了之后,介绍一下博客详情、博客的全文检索模糊查询(这里采用lucene实现)以及博客的分页(在这里采用 同步刷新)logController.java以及评论控制器CommentController.java:

package com.steadyjack.controller;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;import com.steadyjack.entity.Blog;import com.steadyjack.lucene.BlogIndex;import com.steadyjack.service.BlogService;import com.steadyjack.service.CommentService;import com.steadyjack.util.StringUtil;/** * title:BlogController.java * description:前端博客Controller层 * time:2017年1月17日 下午9:44:19 * author:debug-steadyjack */@Controller@RequestMapping("/blog")public class BlogController {@Resourceprivate BlogService blogService;@Resourceprivate CommentService commentService;// 博客索引private BlogIndex blogIndex=new BlogIndex();/** * title:BlogController.java * description:博客详细信息 * time:2017年1月17日 下午9:51:50 * author:debug-steadyjack * @param id * @param request * @throws Exception */@RequestMapping("/articles/{id}")public ModelAndView details(@PathVariable Integer id,HttpServletRequest request)throws Exception{ModelAndView modelAndView=new ModelAndView();Blog blog=blogService.findById(id);String keyWords=blog.getKeyWord();if(StringUtil.isNotEmpty(keyWords)){String arr[]=keyWords.split(" ");modelAndView.addObject("keyWords",StringUtil.filterWhite(Arrays.asList(arr)));}else{modelAndView.addObject("keyWords",null);}modelAndView.addObject("blog", blog);Integer clickHit=blog.getClickHit();clickHit = clickHit==null?0:clickHit+1;//博客点击次数加1blog.setClickHit(clickHit); blogService.update(blog);Map<String,Object> map=new HashMap<String,Object>();//查询审核通过的评论map.put("blogId", blog.getId());map.put("state", 1);//System.out.println(request.getServletContext().getContextPath());modelAndView.addObject("commentList", commentService.list(map)); modelAndView.addObject("pageCode", this.genUpAndDownPageCode(blogService.getLastBlog(id),blogService.getNextBlog(id),request.getServletContext().getContextPath()));modelAndView.addObject("mainPage", "foreground/blog/view.jsp");modelAndView.addObject("pageTitle",blog.getTitle());modelAndView.setViewName("mainTemp");//查询审核通过的评论return modelAndView;}/** * title:BlogController.java * description:根据查询信息查询相关博客信息 * time:2017年1月17日 下午11:11:29 * author:debug-steadyjack * @param q * @param page * @param request * @return ModelAndView * @throws Exception */@RequestMapping("/q")public ModelAndView search(@RequestParam(value="q",required=false)String q,@RequestParam(value="page",required=false)String page,HttpServletRequest request)throws Exception{if(StringUtil.isEmpty(page)){page="1";}ModelAndView mav=new ModelAndView();mav.addObject("mainPage", "foreground/blog/result.jsp");blogIndex.setRequest(request);List<Blog> blogList=blogIndex.searchBlog(q.trim());Integer pageNo=Integer.parseInt(page);Integer pageSize=10;Integer toIndex=blogList.size()>=pageNo*pageSize?pageNo*pageSize:blogList.size();//list的subList是分页的一种:返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图mav.addObject("blogList",blogList.subList((pageNo-1)*pageSize, toIndex));mav.addObject("pageCode",this.genUpAndDownPageCode(pageNo, blogList.size(), q,10,request.getServletContext().getContextPath()));mav.addObject("q",q);mav.addObject("resultTotal",blogList.size());mav.addObject("pageTitle","搜索关键字'"+q+"'结果页面_Java修炼之博客系统");mav.setViewName("mainTemp");return mav;}/** * title:BlogController.java * description: 获取下一篇博客和下一篇博客 * time:2017年1月17日 下午10:14:03 * author:debug-steadyjack * @param lastBlog * @param nextBlog * @param projectContext * @return String */private String genUpAndDownPageCode(Blog lastBlog,Blog nextBlog,String projectContext){StringBuffer pageCode=new StringBuffer();if(lastBlog==null || lastBlog.getId()==null){pageCode.append("<p>上一篇:没有了</p>");}else{pageCode.append("<p>上一篇:<a href='"+projectContext+"/blog/articles/"+lastBlog.getId()+".html'>"+lastBlog.getTitle()+"</a></p>");}if(nextBlog==null || nextBlog.getId()==null){pageCode.append("<p>下一篇:没有了</p>");}else{pageCode.append("<p>下一篇:<a href='"+projectContext+"/blog/articles/"+nextBlog.getId()+".html'>"+nextBlog.getTitle()+"</a></p>");}return pageCode.toString();}/** * 获取上一页,下一页代码 查询博客用到(简单的分页) * @param page 当前页 * @param totalNum 总记录数 * @param q 查询关键字 * @param pageSize 每页大小 * @param projectContext * @return */private String genUpAndDownPageCode(Integer page,Integer totalNum,String q,Integer pageSize,String projectContext){long totalPage=totalNum%pageSize==0?totalNum/pageSize:totalNum/pageSize+1;StringBuffer pageCode=new StringBuffer();if(totalPage==0){return "";}else{pageCode.append("<nav>");pageCode.append("<ul class='pager' >");if(page>1){pageCode.append("<li><a href='"+projectContext+"/blog/q.html?page="+(page-1)+"&q="+q+"'>上一页</a></li>");}else{pageCode.append("<li class='disabled'><a href='#'>上一页</a></li>");}if(page<totalPage){pageCode.append("<li><a href='"+projectContext+"/blog/q.html?page="+(page+1)+"&q="+q+"'>下一页</a></li>");}else{pageCode.append("<li class='disabled'><a href='#'>下一页</a></li>");}pageCode.append("</ul>");pageCode.append("</nav>");}return pageCode.toString();}}

    对于评论控制器,在这里比较简单,只是用于游客进行ip评论(前期没做用户那一块的管理,有兴趣的博友可以自己搞一套!)CommentController.java:

package com.steadyjack.controller;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import net.sf.json.JSONObject;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import com.steadyjack.entity.Blog;import com.steadyjack.entity.Comment;import com.steadyjack.service.BlogService;import com.steadyjack.service.CommentService;import com.steadyjack.util.ResponseUtil;/** * 评论Controller层 * @author Administrator * */@Controller@RequestMapping("/comment")public class CommentController {@Resourceprivate CommentService commentService;@Resourceprivate BlogService blogService;/** * title:CommentController.java * description:添加或者修改评论 * time:2017年1月23日 下午8:02:05 * author:debug-steadyjack * @param comment * @param imageCode * @param request * @param response * @param session * @return * @throws Exception */@RequestMapping("/save")public String save(Comment comment,@RequestParam("imageCode") String imageCode,HttpServletRequest request,HttpServletResponse response,HttpSession session)throws Exception{//获取系统生成的验证码String sRand=(String) session.getAttribute("sRand");JSONObject result=new JSONObject();//操作的记录条数int resultTotal=0; if(!imageCode.equals(sRand)){result.put("success", false);result.put("errorInfo", "验证码填写错误!");}else{//获取用户IPString userIp=request.getRemoteAddr(); comment.setUserIp(userIp);if(comment.getId()==null){resultTotal=commentService.add(comment);//该博客的回复次数加1Blog blog=blogService.findById(comment.getBlog().getId());blog.setReplyHit(blog.getReplyHit()+1);blogService.update(blog);}else{}if(resultTotal>0){result.put("success", true);}else{result.put("success", false);}}ResponseUtil.write(response, result);return null;}}

    最后一个介绍一下“关于博主”/aboutMe请求以及博主登录/login进行认证,通过之后进入后台BloggerController.java:

package com.steadyjack.controller;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import com.steadyjack.entity.Blogger;import com.steadyjack.service.BloggerService;import com.steadyjack.util.CryptographyUtil;/** * title:BloggerController.java * description:博主Controller层 * time:2017年1月23日 下午10:01:10 * author:debug-steadyjack */@Controller@RequestMapping("/blogger")public class BloggerController {@Resourceprivate BloggerService bloggerService;/** * title:BloggerController.java * description:用户登录 * time:2017年1月23日 下午10:01:20 * author:debug-steadyjack * @param blogger * @param request * @return */@RequestMapping("/login")public String login(Blogger blogger,HttpServletRequest request){Subject subject=SecurityUtils.getSubject();UsernamePasswordToken token=new UsernamePasswordToken(blogger.getUserName(), CryptographyUtil.md5(blogger.getPassword(), "debug"));try{//登录验证subject.login(token); return "redirect:/admin/main.jsp";}catch(Exception e){e.printStackTrace();request.setAttribute("blogger", blogger);request.setAttribute("errorInfo", "用户名或密码错误!");return "login";}}/** * title:BloggerController.java * description:查找博主信息 * time:2017年1月23日 下午10:12:45 * author:debug-steadyjack * @return * @throws Exception */@RequestMapping("/aboutMe")public ModelAndView aboutMe()throws Exception{ModelAndView mav=new ModelAndView();mav.addObject("blogger",bloggerService.find());mav.addObject("mainPage", "foreground/blogger/info.jsp");mav.addObject("pageTitle","关于博主_Java开源博客系统");mav.setViewName("mainTemp");return mav;}}

    认证的过程走的是shiro框架的提供MyRealm.java(这在前面已经讲过了):

package com.steadyjack.realm;import javax.annotation.Resource;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import com.steadyjack.entity.Blogger;import com.steadyjack.service.BloggerService;/** * title:MyRealm.java * description:自定义Realm(域) * time:2017年1月22日 下午10:50:57 * author:debug-steadyjack */public class MyRealm extends AuthorizingRealm{@Resourceprivate BloggerService bloggerService;/** * 为当限前登录的用户授予角色和权 * (由于目前系统没有啥资源且只有admin超级用户,故而没写授予角色、权限(资源)逻辑) */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}/** * 验证当前登录的用户 * (成功时,将登陆用户绑定到会话中;失败时,其实会报各种exception,理当抛出用于前端页面展示(后期实现)) */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//获取身份(在这里指 用户名)-凭证(在这里指 密码)String userName=(String)token.getPrincipal();Blogger blogger=bloggerService.getByUserName(userName);if(blogger!=null){//当前用户信息存到session中SecurityUtils.getSubject().getSession().setAttribute("currentUser", blogger); AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(blogger.getUserName(),blogger.getPassword(),getName());return authcInfo;}else{return null;}}}

    最后是贴出效果:










     最后,把WebContent下的页面分享出来:前端用的是bootstrap,后端页面用的是easyui,目录如图:


    页面以及样式来这里下载:

     如果有相关问题:如想找我付费开发其他功能,讨论其中相关问题等等,可以来以下两群找我,我叫debug!

     Java开源技术交流:583522159     鏖战八方群:391619659

阅读全文
0 0