Spring MVC 搭建第一个例子起步(继续SpringMVC hello world)

转载请注明出处:
牵手生活--头条新闻:笔记是整理思路方式,分享是一个美德,牵手是我的生活方式
牵手生活--简书:笔记是整理思路方式,分享是一个美德,牵手是我的生活方式

Postman 使用方法详解
JavaWeb项目放弃jsp?为什么要前后端解耦?为什么要前后端分离?

注:此文承接上一文:Spring MVC -Hello World(环境搭建)下面开始我们的工作

感谢慕课网提供的免费视频,感谢Arthur讲师精彩讲解


web.xml修改对el表达式的支持

修改EL表达式的支持
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

如果涉及涉及到el表达式被关闭,注意web-app的支持版本
关于web.xml中<web-app>报错解决方案

web.xml添加Spring容器的声明

Spring MVC -Hello World搭建并不需要Spring的容器。而我们现在要开始真正搭建Spring MVC,所以我们需要在web.xml中添加Spring的声明

  • ContextLoaderListener
  • 配置信息
  • applicationContext.xml


    web.xml添加spring的支持
  <!-- Spring应用上下文, 理解层次化的ApplicationContext -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/configs/spring/applicationContext*.xml</param-value>
  </context-param>

  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
  • spring 的上下文配置文件:applicationContext.xml
  • springmvc 的DispatcherServlet的上下文配置文件:mvc-dispatcher-servlet.xml

Spring MVC的上下文层级说明:


spring MVC 上下文层级说明

WebApplicaiton Context(s):我们的跟,是有contextLoader加载的形成的上下文,他为我们所以应用提供了公共所使用的一些组件、一些服务;有service层、DAO层等等。这些服务应当是给所以服务所共享的,他一应该被极限在某个DispatcherServlet上下文之中。
WebApplicaiton Context:
DispatcherServlet:可能有多个DispatcherServlet,用不同类型的DispatcherServlet分发不同的请求。在web.xml配置文件中对应的<servlet-maping>中的<url-pattern>用于拦截不同来源的url划分依据,用一个DispatcherServlet来拦截web app根下的请求。


servlet-mapping拦截不同的url

创建Spring上下文相关文件:applicaitonContext.xml配置文件

  • 启动annotation的DI管理
  • 告诉Spring不需要再管理annotation
<?xml version="1.0" encoding="UTF-8"?>
<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/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--启动annotation的DI管理  -->
    <context:annotation-config />
    <!-- 告诉Spring不需要再管理annotation -->
    <context:component-scan base-package="com.younghare.mvcdemo">
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
</beans>

mvc-dispatcher-servlet.xml配置说明

注 :本配置文件是工名为mvc-dispatcher的DispatcherServlet使用, 提供其相关的Spring MVC配置

  • <context:annotation-config />部分:启用Spring基于annotation的DI, 使用户可以在Spring MVC中使用Spring的强大功能。 激活 @Required ,@Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等标注

  • <context:component-scan>部分:告诉DispatcherServlet上下文, 只管理(扫描)@Controller类型的bean即可, 忽略其他型的bean,不需要去管理service,service交给我们的spring上下文去管理。

  • HandlerMapping:HandlerMapping, 无需配置, Spring MVC有很强大的默认启动,如果我们不进行任何配置,他将启用我们的默认配置。默认配置会启动DefaultAnnotationHandlerMapping,这个类就可以为我们去解析我们注解的 annotation-driven HandlerMapping。

  • <mvc:annotation-driven />:这配置扩展了我么的驱动注解,他可以进一步的将我么请求参数绑定到控制器参数 ;也就是url中的查询的某个变量,可以直接映射到Controller中某个方法的输入参数。

  • ViewResolver bean的配置:dispatcher-servlet中可以依次的配置多个ViewResolver,他们之间可以使用order属性进行排序,唯一注意的是InternalResourceViewResolver必须放在最后,因为他必定会返回一个对象

  • 静态资源处理,如果没有这些配置我们将无法获得静态资源


    image.png
  • mvc:resources :这部分就是我们要添加的,如果没有这些配置,我就讲无法获得我们的的静态资源,比如: css, js, imgs -。比如resources及时把resources映射到我们本地目录的resources目录下。


修改mvc-dispatcher-servlet.mxl配置

资源映射关系

添加到mvc-dispatcher-servlet.xml代码
注意:目录项目资源名称的resources也,本地映射的resources目录名称要与配置中保持一致

    <!-- 静态资源处理, css, js, imgs -->
    <!--这个在hello world项目中没有 后面的location="/resources/" 通常用于存放css、js、image-->
    <mvc:resources mapping="/resources/**" location="/resources/" />

修复日志部分的错误-创建log4j.properties

缺少配置文件警告信息
log4j.properties配置

log4j.properties配置信息

log4j.appender.Cons=org.apache.log4j.ConsoleAppender
log4j.appender.Cons.layout=org.apache.log4j.PatternLayout
log4j.appender.Cons.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

# Root logger set to DEBUG using the A2 appender defined above.
log4j.rootLogger=info, Cons 
log4j.additivity=false

#Application Logger+
log4j.logger.com.imooc.mvcdemo=debug, Cons
log4j.logger.org.springframework=debug, Cons
log4j.additivity.com=false

java日志框架log4j详细配置及与slf4j联合使用教程


完成上述的工作,说明的的Spring MVC环境才真正搭建起来,下面开始Spring MVC 方面的真正开放运用。

SpringMVC Controller开发基础设施Model、service、展示的jsp、其他资源(css、image、js)、Controller

先看一下目录结构

SpringMVC+Controller的目录结构

关注service的spring注解

service注解用Spring注解

Spring MVC controller用到的Model

  • Chapter.java (章节)
  • Course.java( 课程)
model关系

Spring MVC controller用到的service(接口&接口实现)

  • Course mode相关的服务类CourseService(没用用到数据库,使用硬代码的方式完成课程的组装,在下篇中将介绍如何接入mysql数据库)
    CourseService.java(接口)
    CourseServiceImpl.java(接口实现)

Spring MVC controller用到的jsp

  • course_overview.jsp

Spring MVC controller用到的其他资源(css、image、js)

Spring MVC controller本身CourseController.java

package com.younghare.mvcdemo.controller;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.younghare.mvcdemo.model.Course;
import com.younghare.mvcdemo.service.CourseService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;



//告诉spring mvc的dispatcher-servlet这时一个Controller,会被dispatcher-servlet所管理,并且依赖注入
@Controller
//类级别的RequestMapping,它处理我们Controller的根url
@RequestMapping("/courses")
// /courses/**
public class CourseController {
    
    private static Logger log = LoggerFactory.getLogger(CourseController.class);

    private CourseService courseService;

    @Autowired
    public void setCourseService(CourseService courseService) {
        this.courseService = courseService;
    }

    
    //本方法将处理 /courses/view?courseId=123 形式的URL
    @RequestMapping(value="/view", method=RequestMethod.GET)
    //方法内的@RequestParam注释用来表示url请求的参数
    public String viewCourse(@RequestParam("courseId") Integer courseId,
            Model model) {
        
        
        log.debug("In viewCourse, courseId = {}", courseId);
        //获取课程,并把课程信息通过session返回给jsp
        Course course = courseService.getCoursebyId(courseId);
        model.addAttribute(course);
        return "course_overview";
    }
    
    //本方法将处理 /courses/view2/123 形式的URL
    @RequestMapping("/view2/{courseId}")
    public String viewCourse2(@PathVariable("courseId") Integer courseId,
            Map<String, Object> model) {
        
        log.debug("In viewCourse2, courseId = {}", courseId);
        Course course = courseService.getCoursebyId(courseId);
        model.put("course",course);
        return "course_overview";
    }

    //传统的HttpServletRequest参数方式处理
    //本方法将处理 /courses/view3?courseId=123 形式的URL
    @RequestMapping("/view3")
    public String viewCourse3(HttpServletRequest request) {
        
        Integer courseId = Integer.valueOf(request.getParameter("courseId"));       
        Course course = courseService.getCoursebyId(courseId);
        request.setAttribute("course",course);
        
        return "course_overview";
    }

    //添加模拟操作
    @RequestMapping(value="/admin", method = RequestMethod.GET, params = "add")
    public String createCourse(){
        return "course_admin/edit";
    }

    //保存模拟操作
    @RequestMapping(value="/save", method = RequestMethod.POST)
    //@ModelAttribute参数级别的标签实现页面对象与
    public String  doSave(@ModelAttribute Course course){       
        
        log.debug("Info of Course:");
        log.debug(ReflectionToStringBuilder.toString(course));
        
        //在此进行业务操作,比如数据库持久化
        course.setCourseId(123);
        //重定向自己其他方法的url
        return "redirect:view2/"+course.getCourseId();
    }

    //SpringMVC内置了文件上传功能,我们只需通过一些配置,就可以使用Spring给我们暴露的接口实现文件上传
    //上传操作
    @RequestMapping(value="/upload", method=RequestMethod.GET)
    public String showUploadPage(@RequestParam(value= "multi", required = false) Boolean multi){    
        if(multi != null && multi){
            return "course_admin/multifile";    
        }
        return "course_admin/file";     
    }

    //文件上传
    @RequestMapping(value="/doUpload", method=RequestMethod.POST)
    //MultipartFile:是SpringMVC提供的一个文件上传类;@RequestParam指定文件上传input 的name=file
    public String doUploadFile(@RequestParam("file") MultipartFile file) throws IOException{
        
        if(!file.isEmpty()){
            log.debug("Process file: {}", file.getOriginalFilename());
            //copy 输入流到服务器的c:\temp\younghare
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\\temp\\younghare\\", System.currentTimeMillis()+ file.getOriginalFilename()));
        }
        
        return "success";
    }
    
    @RequestMapping(value="/doUpload2", method=RequestMethod.POST)
    public String doUploadFile2(MultipartHttpServletRequest multiRequest) throws IOException{
        
        Iterator<String> filesNames = multiRequest.getFileNames();
        while(filesNames.hasNext()){
            String fileName =filesNames.next();
            MultipartFile file =  multiRequest.getFile(fileName);
            if(!file.isEmpty()){
                log.debug("Process file: {}", file.getOriginalFilename());
                FileUtils.copyInputStreamToFile(file.getInputStream(), new File("c:\\temp\\younghare\\", System.currentTimeMillis()+ file.getOriginalFilename()));
            }
            
        }
        
        return "success";
    }
    
    
    //直接返回json数据
    //http://localhost:8080/courses/123
    //jquery的异步动态加载:http://localhost:8080/course_json.jsp?courseId=123
    @RequestMapping(value="/{courseId}",method=RequestMethod.GET)
    public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
        return  courseService.getCoursebyId(courseId);
    }

    //SpringMVC对json的支持
    //http://localhost:8080/courses/jsontype/123
    @RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
    //ResponseEntity类可以可以把数据模型转换成json格式
    public  ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
        Course course =   courseService.getCoursebyId(courseId);        
        return new ResponseEntity<Course>(course, HttpStatus.OK);
    }
    
    
    
}

出现问题解决:


image.png

IntelliJ IDEA :Error:(1, 1) java: 非法字符: '\ufeff'

运行工程,并在浏览器上直接访问CourseController控制器对应的地址

地址如:

http://localhost:8080/courses/view?courseId=5

http://localhost:8080/courses/view2/123

运行效果如下


日志输出
浏览器直接url访问

添加的编辑url

http://localhost:8080/courses/admin?add
编辑页面

点击提交后可以多看到日志输出


点击提交日志输出

碰到问题:没有打印日志情况
log4j 设置日志输出文件的路径

log4j配置参数不要搞错

文件上传Spring提供了一个bean:CommonsMultipartResolver

SpringMVC内置了文件上传功能,我们只需通过一些配置,就可以使用Spring给我们暴露的接口实现文件上传
需要apache的ommons-fileupload包支持

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
文件上传配置

    <!--200*1024*1024即200M resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常
    maxUploadSize:上传文件大小限制
    defaultEncoding:编码
     resolveLazily:是否延迟加载
    -->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="209715200" />
        <property name="defaultEncoding" value="UTF-8" />
        <property name="resolveLazily" value="true" />
    </bean>

文件上传的url

http://localhost:8080/courses/upload
上传文件选择页面
上传观察资源管理器的情况
文件上传成功提示

SpringMVC对json的支持mvc-dispatcher-servlet.xml添加配置bean的ContentNegotiatingViewResolver类(后来发现这个配置已经过时,后面有问题描述及解决办法)

    <!-- 配置ViewResolver。 可以用多个ViewResolver。 使用order属性排序。 InternalResourceViewResolver放在最后。 -->
    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
                <entry key="htm" value="text/html" />
            </map>
        </property>

        <property name="defaultViews">
            <list>
                <!-- JSON View -->
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                </bean>
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true" />
    </bean>

碰到问题


配置SpringMVC 对json支持不能认识

参考:

ContentNegotiationConfigurer (Spring Framework 4.3.2.RELEASE API)

https://docs.spring.io/autorepo/.../ContentNegotiationConfigurer.html

翻译此页

ignoreAcceptHeader(boolean) · Header strategy, On ... Whether to ignore requests with path extension that cannot be resolved to any media type. ... When favorPathExtension(boolean) is set, this propertydetermines whether to allow use of JAF (Java Activation Framework) to resolve a path extension to a specific ...

找不到属性

mediaTypes错误(Bean property 'mediaTypes' is not writable or has an invalid setter method.)

修改对mvc-dispatcher-servlet.xml对json的支持(同时记得删除错误的配置)

    <bean id="contentNegotiationManagerFactoryBean" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"
          p:favorPathExtension="false" p:favorParameter="true" p:parameterName="format" p:ignoreAcceptHeader="true"
          p:defaultContentType="application/json">
        <property name="mediaTypes">
            <props>
                <prop key="json">application/json</prop>
                <prop key="xml">application/xml</prop>
            </props>
        </property>
    </bean>
    <bean
            class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"
            p:favorPathExtension="false" p:favorParameter="true"
            p:parameterName="format" p:ignoreAcceptHeader="true"
            p:defaultContentType="application/json">
        <property name="mediaTypes">
            <props>
                <prop key="json">application/json</prop>
                <prop key="xml">application/xml</prop>
            </props>
        </property>
    </bean>

返回json的url

http://localhost:8080/courses/123

http://localhost:8080/courses/jsontype/123
返回json数据

jsp对后台请求的异步处理course_json.jsp (采用到的是jquery库中的ajax异步访问技术,记得如果有更换jquery版本要在这个json中做引用的修改)

<script type="text/javascript"      
    <%--src="<%=request.getContextPath()%>/resources/js/jquery-1.11.3.min.js"></script>--%>
        src="<%=request.getContextPath()%>/resources/js/jquery-3.3.1.min.js"></script>

</head>

image.png

jsp异步获取json数据处理的url

http://localhost:8080/course_json.jsp?couseId=123
image.png

course_json.jsp 源码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring  MVC json 返回异步处理</title>

<link rel="stylesheet"
    href="<%=request.getContextPath()%>/resources/css/main.css"
    type="text/css" />
<script type="text/javascript"
    <%--src="<%=request.getContextPath()%>/resources/js/jquery-1.11.3.min.js"></script>--%>
        src="<%=request.getContextPath()%>/resources/js/jquery-3.3.1.min.js"></script>

</head>
<script>
jQuery(function($){
    var urlStr = "<%=request.getContextPath()%>/courses/<%=request.getParameter("courseId")%>";
    //alert("Before Call:"+urlStr);
    $.ajax({  //调用jQuery中的ajax
        method: "GET", //才用get方式请求
        url: urlStr, //ajax 访问web后端的地址
        success:function(data,status,jqXHR){//ajax拿到数据之后动态加载dom的方式加载数据
            //alert("Success:"+data);
            var course = data;
            var path = "<%=request.getContextPath()%>/";    
            $(".course-title").html(course.title);//动态加载dom的方式加载数据
            $(".course_video").attr("src", path+course.imgPath);
            $("#learningNum").text(course.learningNum);
            $("#duration").text(course.duration);
            $("#levelDesc").text(course.levelDesc);
            $(".course_shortdecription").html(course.descr);
            
            var chapterList = course.chapterList;
            var chapter;
            
            for(var i = 0;i<chapterList.length;i++){
                chapter = chapterList[i];   
                
                var liObj = $("li",$("#chapterTemplate")).clone();               
                $(".outline_name", liObj).text(chapter.title);
                $(".outline_descr", liObj).text(chapter.descr);             
                liObj.appendTo("#couList");             
            }// ~ end for           
        }
    }); // end ajax
});
</script>
<body>


    <div id="main">

        <div class="newcontainer" id="course_intro">
            <div class="course-title"></div>
            <div class="course_info">
                <div class="course-embed l">
                    <div id="js-course-img" class="img-wrap">
                        <img width="600" height="340" alt=""
                            class="course_video" />
                    </div>
                    <div id="js-video-wrap" class="video" style="display: none">
                        <div class="video_box" id="js-video"></div>
                    </div>
                </div>
                <div class="course_state">
                    <ul>
                        <li><span>学习人数</span> <em id="learningNum"></em></li>
                        <li class="course_hour"><span>课程时长</span> <em
                            class="ft-adjust"><span id="duration"></span>秒</em></li>
                        <li><span>课程难度</span> <em id="levelDesc"></em></li>
                    </ul>
                </div>

            </div>
            <div class="course_list">
                <div class="outline">
                    <h3 class="chapter_introduces">课程介绍</h3>
                    <div class="course_shortdecription"></div>

                    <h3 class="chapter_catalog">课程提纲</h3>
                    <ul id="couList">
                        
                    </ul>
                </div>

            </div>
        </div>

    </div>

    <div id="chapterTemplate"  style="display:none">
       <li class="clearfix open"><a href="#">
                <div class="openicon"></div>
                <div class="outline_list l">
                        <h5 class="outline_name"></h5>
                        <p class="outline_descr"></p>
                </div>
         </a></li>
    </div>

</body>
</html>

所以工作全部完成后目录结构

完成后的目录结构
Maven引入的内容

下面把用到的代码贴出来

代码下载地址

https://yunpan.360.cn/surl_yQXTvTU5vFb (提取码:1a1c)

不错的源码推荐:
Spring+SpringMvc+MyBatis+Redis基于SSM-EasyUI的权限管理系统

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,733评论 6 342
  • Spring MVC一、什么是 Spring MVCSpring MVC 属于 SpringFrameWork 的...
    任任任任师艳阅读 3,372评论 0 32
  • 学习资料源:慕课网 - Spring MVC起步 内容概要 一、前端控制器(Front Controller) 二...
    拾壹北阅读 1,956评论 0 22
  • 出发——妩媚与呆萌 此时看到一个散落的城镇的公路上正驶过一辆贴着“德卧-兴义”的中巴。人们的房顶都建有太阳能热水器...
    心灵复兴阅读 780评论 1 2