当前位置: 首页 > news >正文

[java 手把手教程][第二季]java 后端博客系统文章系统——No7

转眼间又到了三月花开的季节,没一起感觉开篇都在说一些废话,这一期一样不例外。

项目github地址:github.com/pc859107393…

实时项目同步的地址是国内的码云:git.oschina.net/859107393/m…

我的简书首页是:www.jianshu.com/users/86b79…

上一期是:[手把手教程][第二季]java 后端博客系统文章系统——No6

行走的java全栈

工具

  • IDE为idea16
  • JDK环境为1.8
  • gradle构建,版本:2.14.1
  • Mysql版本为5.5.27
  • Tomcat版本为7.0.52
  • 流程图绘制(xmind)
  • 建模分析软件PowerDesigner16.5
  • 数据库工具MySQLWorkBench,版本:6.3.7build

本期目标

  • 回顾SpringMvc
  • 总结提高

闲聊

最近看了很多技术相关的文档感觉受益良多,我也会不定时的在群里分享一些技术文档,虽然很多都是别人分享给我的。

世上无难事,只要肯攀登。(肯攀登是谁呢?)

虽然说我们是单独做技术的人,但是牛奶和面包总是不能少的。一味画饼充饥的创业都是耍流氓。

最近碰到几个想找我一起创业的人,不签合同,不给现金,都是吹逼项目牛逼,然后想我白干。 可惜我已经过了几句煽情的话就能打动的年纪。

无论谁找你创业,不给真金白银都是耍流氓。

SpringMvc

在前面我们已经做过很多关于SpringMvc的应用,可能大家很多日常的基本操作都有了概念,但是这个操作叫做什么名字呢?怎样更加合理的运用呢?Let's go!

1. 配置SpringMvc

我们需要创建Spring-Web.xml,代表它是我们的Spring依赖的注册文件(context)。

<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"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">复制代码

上面演示的是我们注册的时候需要的Spring相关的申明。紧接着,我们需要开始一步步的注册web相关的资源:

<!-- 配置SpringMVC --><!-- 1.开启SpringMVC注解模式 --><!-- 简化配置:(1)自动注册DefaultAnootationHandlerMapping,AnotationMethodHandlerAdapter(2)提供一些列:数据绑定,数字和日期的format @NumberFormat, @DateTimeFormat, xml,json默认读写支持--><mvc:annotation-driven/>复制代码

当我们引入了上面的代码的时候,我们已经开启了SpringMvc的注解映射(同理我们可以使用非注解映射!)

  • 简单的说明下非注解映射就是在Spring-web.xml中直接配置url。

当我们配置了url的访问注解后,按照道理来说只要我们开始配置了,那么我们的地址就是可以开始访问的,但是我们不可能所有的请求都需要框架来处理然后转发吧?so,我们需要配置一些特殊资源的访问路径,比如说静态的js、css、img等等,所以有了如下的配置:

    <!--配置静态资源的url映射--><mvc:resources mapping="/css/**" location="/static/css/"/><mvc:resources mapping="/images/**" location="/static/images/"/><mvc:resources mapping="/view/**" location="/static/view/"/><mvc:resources mapping="/js/**" location="/static/js/"/><mvc:resources mapping="/fonts/**" location="/static/fonts/"/><!--配置默认的前端控制器--><mvc:default-servlet-handler/>复制代码

当然,我们上面得只是简单的配置了一些文件的url目录,同时我们可以部署我们的线上资源的访问权限,如果是非法用户那么就需要把他赶出服务器,所以我们需要请求拦截,并插入一些代码检查之类的操作,所以先配置拦截器如下:

    <!-- 访问拦截  --><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**/**"/><bean class="cn.acheng1314.intercepter.LoginHandlerInterceptor"/></mvc:interceptor></mvc:interceptors>复制代码

具体的拦截器代码如下:


/*** Created by mac on 2017/1/27.*/
public class LoginHandlerInterceptor extends HandlerInterceptorAdapter {@Autowiredprivate UserService userService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String path = request.getServletPath();String userId;  //登录成功后写入session的用户idUser user;  //通过用户ID查询到的用户信息/*我们拦截的网址是需要最少是作者权限才能进行编辑的,所以这里我们需要限制访问。<br/> 同时我们可以看到的是 登录页面必须是所有人都可以访问的,但是如果已经登录成功了,session在有效期内,我们的登录界面就不应该再展示给用户*/if (!path.matches(".*/((endSupport)|(commit*)).*")) {if (path.contains("/main/login")) { //已经登录且身份信息且没有过期,我们直接跳转到后端主页去try {userId = request.getSession().getAttribute("userId").toString();user = userService.findOneById(userId);if (request.getRequestedSessionId().equals(user.getUserSessionId())) {  //前面用户登录后会存入请求的sessionId和当前的sessionId对比response.sendRedirect(request.getContextPath() + "/endSupport/index");return false;}} catch (Exception e) {e.printStackTrace();return true;}}return true;} else {try {userId = request.getSession().getAttribute("userId").toString();user = userService.findOneById(userId);if (!request.getRequestedSessionId().equals(user.getUserSessionId())) {  //前面用户登录后会存入请求的sessionId和当前的sessionId对比throw new Exception("用户信息错误!");}return true;} catch (Exception e) {e.printStackTrace();response.sendRedirect(request.getContextPath() + "/main/login");return false;}}}
}复制代码

看到上面拦截器相关的代码,大家都会明白,在我的url中只要匹配了endSupport和commit相关字段的,我们都需要用户登录,其实说严格一点按照http请求的几种方式和restful来说没我们需要匹配更多的规则才行。重点思考:我们既然前面看到了拦截器那里仅仅配置了一个拦截器,那么我们能不能配置多个拦截器呢?答案是可以的,interceptors:指定拦截器链,拦截器的执行顺序就是此处添加拦截器的顺序。

通过上面的配置,我们已经可以实现html页面的展示,而且依赖js脚本刷新的动态页面也是基本可以显示了,但是,不是所有的后端工程师都精通web页面的开发,更多时候,可能我们单纯的更喜欢jsp这种方式的页面,所以我们需要添加jsp页面的解析,代码如下:

    <!-- 3.配置jsp 显示ViewResolver --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean>复制代码

配置完成到这里,我们需要的就只剩下文件上传的数据模型和web接口的扫描了。为什么要扫描web接口呢?我们前面开启了注解映射,那么我们避免和项目其他的冲突,我们直接指定web接口的文件存放目录,让程序完成自动扫描,那么我们就只需要关心我们的业务开发了,是不是很爽?

    <!--上传文件的处理模型--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="10000000"/></bean><!-- 4.扫描web相关的bean --><context:component-scan base-package="cn.acheng1314.controller"><!-- 制定扫包规则 ,只扫描使用@Controller注解的JAVA类 --><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>复制代码

小结

SpringMvc的配置顺序如下:

创建配置文件→加入依赖申明→开启注解式映射(非注解也行)→加入特殊资源访问映射→设置访问拦截→配置动态视图解析→配置web接口扫描规则和文件上传的处理模型。

既然已经配置好了注解开发设置,那么我们需要实际操作体会一下SpringMvc的开发,先看看代码如下:

@Controller
@RequestMapping("/front")
public class FrontWebController {/*** 返回主页面** @return*/@RequestMapping(value = "/main", method = RequestMethod.GET)public ModelAndView frontMain(HttpServletRequest request) throws Exception {ModelAndView view = new ModelAndView("frontMain");view.addObject("framJson", getFramJson());view.addObject("postsJson", findPublishPost(request, 1, 10));return view;}复制代码

在上面得代码中我们是返回一个web页面,这个web页面匹配到的url就是:xxxhost.xxx/front/main。主要规则说明如下:

  1. 类用Controller的注解:@Controller,说明这个类是web接口的注册类
  2. RequestMapping的意思是说明这个地址是:“/RequestMapping”
  3. http请求的方式有很多,可以在RequestMapping中限制具体的请求方式是什么?

    • 具体的形式有:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
    • 我们在RequestMapping中发现有更多的说明,如:name、value、path、method、params、headers、consumes、produces,具体的其他用途我们可以详细的查看文档。
  4. ModelAndView主要是用来说明这个请求地址是个web视图。
  5. view.addObject() 是用来将我们希望传输到web页面的数据插入到请求中
  6. 在web页面中,我们使用${objName}来获取数据。

通过上面得代码和归纳,我们大概明白了怎么去创建一个web页面需要怎么样的设置,但是我们如果要获取到json数据呢?具体如下:

@RequestMapping(value = "/findPublishPost", produces = {APPLICATION_JSON_UTF8_VALUE}, method = {RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic Object findPublishPost(HttpServletRequest request,@RequestParam(value = "pageNum", required = false)Integer pageNum,@RequestParam(value = "pageSize", required = false)Integer pageSize) throws Exception {return "这是返回的json数据";}复制代码

上面得代码我们可以得到json数据,为什么呢?

  1. 首先我们可以看到我们的RequestMapping多了produces和method。produces是对这个方法的综述,method是这个请求的访问方法,重要的是他们都是数组,也就是可以支持多种形式。
  2. ResponseBody这个注解是专门用来修饰某个方法,说明这个方法只返回ResponseBody(响应体)。
  3. RequestParam标记这个请求的参数,默认值是TRUE,除非单独表明required = false

这就完了吗?等等呢,还没完。为啥呢?我们想象一下,当我们要去找人的时候,是不是直接叫xx出来呢?既然这样,我现在需要从一个列表中拿到数据,是不是也应该这样呢?

    /*** RESTful风格的文章页面** @param postId 文章ID* @return 返回文章页面*/@RequestMapping(path = "/post/{postId}", method = RequestMethod.GET)public ModelAndView getPostView(@PathVariable int postId) {ModelAndView resultView = new ModelAndView("frontPost");resultView.addObject("framJson", getFramJson());resultView.addObject("postJson", getPostById(postId));return resultView;}复制代码

上线这段代码,我们最终可以看到一个文章详情页,而且重点的是“post/”后面的postId发生了变化,其他的都是对应着变化的。

  1. 首先在方法上面注解RequestMapping说明请求地址。
  2. path = "/post/{postId}" 说明url的形式是:/post/xxx。
  3. @PathVariable int postId说明这里参数postId和上面的{postId}的值相同。

说实话,到了上面这样子,其实大概东西都差不多了,不过需要注意的重点就是:web接口中的参数永远你都是不知道存不存在的,所以使用基本数据类型的参数都是不安全的,所以我们需要使用包装类型。

总结

Spring+SpringMvc类型的框架中,SpringMvc提供了web试图的填充和解析以及http请求的接收、处理和响应,所以我们需要先配置web相关设置,后面才能进行web相关的开发。


最后扯犊子一下,关于中国人、乐天、萨德和韩国我觉得尊重中国人,保护私有财产,韩国棒子滚一边去。


http://www.taodudu.cc/news/show-2639136.html

相关文章:

  • 【physx/wasm】在physx中添加自定义接口并重新编译wasm
  • excel---常用操作
  • Lora训练Windows[笔记]
  • linux基础指令讲解(ls、pwd、cd、touch、mkdir)
  • InnoDB 事务处理机制
  • 启明云端ESP32 C3 模组WT32C3通过 MQTT 连接 AWS
  • 数据库学习纪要(十二):SQL Sever介绍-4
  • MapReduce之幺半群
  • 【后端】--process information unavailable解决办法[详细版]
  • ISCC2017 Misc write up附件题目文件
  • [割点问题]HOJ 12307 Disconnected Pair
  • 计算几何专项:UVa 12307
  • asp dotnet core 从零开始创建一个 WebApi 服务
  • UVa 12307 Smallest Enclosing Rectangle(旋转卡壳+最小覆盖矩形)
  • uva 12307(点集的外接矩形)
  • UVA 12307 Smallest Enclosing Rectangle(旋转卡壳)
  • uva 12307 - Smallest Enclosing Rectangle(旋转卡壳)
  • UVA 12307 Smallest Enclosing Rectangle
  • UVA 12307 旋转卡壳
  • uva12307(旋转卡壳)
  • UVA12307 Smallest Enclosing Rectangle 题解
  • numpy.ptp
  • gPTP与PTP理解资料参考
  • linux下ptp性能测试
  • 时统ptp_IEEE1588 PTP对时系统原理及特点
  • 时统ptp_IEEE1588对时系统,PTP校时模块,PTP时钟服务器
  • linuxptp源码研究
  • ptp输出内容包含什么_PTP技术及其应用分析
  • IEEE1588 Precision Time Protocol(PTP)
  • Linuxptp安装部署
  • Ubuntu 设置PTP时间同步
  • PTP时间同步
  • ptp4l linux,如何使用PTP4l测试PTPV2协议精度?
  • android ptp 源码分析,ptp增加豆瓣评分
  • PTP移植
  • linuxptp分析