Spring MVC 搭建第一個(gè)例子起步(繼續(xù)SpringMVC hello world)

轉(zhuǎn)載請(qǐng)注明出處:
牽手生活--頭條新聞:筆記是整理思路方式,分享是一個(gè)美德,牽手是我的生活方式
牽手生活--簡(jiǎn)書:筆記是整理思路方式妇蛀,分享是一個(gè)美德耕突,牽手是我的生活方式

Postman 使用方法詳解
JavaWeb項(xiàng)目放棄jsp?為什么要前后端解耦评架?為什么要前后端分離眷茁?

注:此文承接上一文:Spring MVC -Hello World(環(huán)境搭建)下面開始我們的工作

感謝慕課網(wǎng)提供的免費(fèi)視頻,感謝Arthur講師精彩講解


web.xml修改對(duì)el表達(dá)式的支持

修改EL表達(dá)式的支持
<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表達(dá)式被關(guān)閉纵诞,注意web-app的支持版本
關(guān)于web.xml中<web-app>報(bào)錯(cuò)解決方案

web.xml添加Spring容器的聲明

Spring MVC -Hello World搭建并不需要Spring的容器上祈。而我們現(xiàn)在要開始真正搭建Spring MVC,所以我們需要在web.xml中添加Spring的聲明

  • ContextLoaderListener
  • 配置信息
  • applicationContext.xml


    web.xml添加spring的支持
  <!-- Spring應(yīng)用上下文, 理解層次化的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的上下文層級(jí)說明:


spring MVC 上下文層級(jí)說明

WebApplicaiton Context(s):我們的跟挣磨,是有contextLoader加載的形成的上下文雇逞,他為我們所以應(yīng)用提供了公共所使用的一些組件、一些服務(wù)茁裙;有service層塘砸、DAO層等等。這些服務(wù)應(yīng)當(dāng)是給所以服務(wù)所共享的晤锥,他一應(yīng)該被極限在某個(gè)DispatcherServlet上下文之中掉蔬。
WebApplicaiton Context:
DispatcherServlet:可能有多個(gè)DispatcherServlet,用不同類型的DispatcherServlet分發(fā)不同的請(qǐng)求矾瘾。在web.xml配置文件中對(duì)應(yīng)的<servlet-maping>中的<url-pattern>用于攔截不同來源的url劃分依據(jù)女轿,用一個(gè)DispatcherServlet來攔截web app根下的請(qǐng)求。


servlet-mapping攔截不同的url

創(chuàng)建Spring上下文相關(guān)文件:applicaitonContext.xml配置文件

  • 啟動(dòng)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">

    <!--啟動(dòng)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使用壕翩, 提供其相關(guān)的Spring MVC配置

  • <context:annotation-config />部分:?jiǎn)⒂肧pring基于annotation的DI, 使用戶可以在Spring MVC中使用Spring的強(qiáng)大功能蛉迹。 激活 @Required ,@Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等標(biāo)注

  • <context:component-scan>部分:告訴DispatcherServlet上下文放妈, 只管理(掃描)@Controller類型的bean即可北救, 忽略其他型的bean,不需要去管理service芜抒,service交給我們的spring上下文去管理珍策。

  • HandlerMapping:HandlerMapping, 無需配置, Spring MVC有很強(qiáng)大的默認(rèn)啟動(dòng)宅倒,如果我們不進(jìn)行任何配置攘宙,他將啟用我們的默認(rèn)配置。默認(rèn)配置會(huì)啟動(dòng)DefaultAnnotationHandlerMapping拐迁,這個(gè)類就可以為我們?nèi)ソ馕鑫覀冏⒔獾?annotation-driven HandlerMapping蹭劈。

  • <mvc:annotation-driven />:這配置擴(kuò)展了我么的驅(qū)動(dòng)注解,他可以進(jìn)一步的將我么請(qǐng)求參數(shù)綁定到控制器參數(shù) 线召;也就是url中的查詢的某個(gè)變量链方,可以直接映射到Controller中某個(gè)方法的輸入?yún)?shù)。

  • ViewResolver bean的配置:dispatcher-servlet中可以依次的配置多個(gè)ViewResolver灶搜,他們之間可以使用order屬性進(jìn)行排序祟蚀,唯一注意的是InternalResourceViewResolver必須放在最后工窍,因?yàn)樗囟〞?huì)返回一個(gè)對(duì)象

  • 靜態(tài)資源處理,如果沒有這些配置我們將無法獲得靜態(tài)資源


    image.png
  • mvc:resources :這部分就是我們要添加的前酿,如果沒有這些配置患雏,我就講無法獲得我們的的靜態(tài)資源,比如: css罢维, js淹仑, imgs -。比如resources及時(shí)把resources映射到我們本地目錄的resources目錄下肺孵。


修改mvc-dispatcher-servlet.mxl配置

資源映射關(guān)系

添加到mvc-dispatcher-servlet.xml代碼
注意:目錄項(xiàng)目資源名稱的resources也匀借,本地映射的resources目錄名稱要與配置中保持一致

    <!-- 靜態(tài)資源處理, css平窘, js吓肋, imgs -->
    <!--這個(gè)在hello world項(xiàng)目中沒有 后面的location="/resources/" 通常用于存放css、js瑰艘、image-->
    <mvc:resources mapping="/resources/**" location="/resources/" />

修復(fù)日志部分的錯(cuò)誤-創(chuàng)建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詳細(xì)配置及與slf4j聯(lián)合使用教程


完成上述的工作是鬼,說明的的Spring MVC環(huán)境才真正搭建起來,下面開始Spring MVC 方面的真正開放運(yùn)用紫新。

SpringMVC Controller開發(fā)基礎(chǔ)設(shè)施Model均蜜、service、展示的jsp芒率、其他資源(css囤耳、image、js)偶芍、Controller

先看一下目錄結(jié)構(gòu)

SpringMVC+Controller的目錄結(jié)構(gòu)

關(guān)注service的spring注解

service注解用Spring注解

Spring MVC controller用到的Model

  • Chapter.java (章節(jié))
  • Course.java( 課程)
model關(guān)系

Spring MVC controller用到的service(接口&接口實(shí)現(xiàn))

  • Course mode相關(guān)的服務(wù)類CourseService(沒用用到數(shù)據(jù)庫紫皇,使用硬代碼的方式完成課程的組裝,在下篇中將介紹如何接入mysql數(shù)據(jù)庫)
    CourseService.java(接口)
    CourseServiceImpl.java(接口實(shí)現(xiàn))

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這時(shí)一個(gè)Controller,會(huì)被dispatcher-servlet所管理化焕,并且依賴注入
@Controller
//類級(jí)別的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)
    //方法內(nèi)的@RequestParam注釋用來表示url請(qǐng)求的參數(shù)
    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";
    }

    //傳統(tǒng)的HttpServletRequest參數(shù)方式處理
    //本方法將處理 /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參數(shù)級(jí)別的標(biāo)簽實(shí)現(xiàn)頁面對(duì)象與
    public String  doSave(@ModelAttribute Course course){       
        
        log.debug("Info of Course:");
        log.debug(ReflectionToStringBuilder.toString(course));
        
        //在此進(jìn)行業(yè)務(wù)操作撒桨,比如數(shù)據(jù)庫持久化
        course.setCourseId(123);
        //重定向自己其他方法的url
        return "redirect:view2/"+course.getCourseId();
    }

    //SpringMVC內(nèi)置了文件上傳功能查刻,我們只需通過一些配置,就可以使用Spring給我們暴露的接口實(shí)現(xiàn)文件上傳
    //上傳操作
    @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提供的一個(gè)文件上傳類凤类;@RequestParam指定文件上傳input 的name=file
    public String doUploadFile(@RequestParam("file") MultipartFile file) throws IOException{
        
        if(!file.isEmpty()){
            log.debug("Process file: {}", file.getOriginalFilename());
            //copy 輸入流到服務(wù)器的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數(shù)據(jù)
    //http://localhost:8080/courses/123
    //jquery的異步動(dòng)態(tài)加載: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對(duì)json的支持
    //http://localhost:8080/courses/jsontype/123
    @RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
    //ResponseEntity類可以可以把數(shù)據(jù)模型轉(zhuǎn)換成json格式
    public  ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
        Course course =   courseService.getCoursebyId(courseId);        
        return new ResponseEntity<Course>(course, HttpStatus.OK);
    }
    
    
    
}

出現(xiàn)問題解決:


image.png

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

運(yùn)行工程穗泵,并在瀏覽器上直接訪問CourseController控制器對(duì)應(yīng)的地址

地址如:

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

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

運(yùn)行效果如下


日志輸出
瀏覽器直接url訪問

添加的編輯url

http://localhost:8080/courses/admin?add
編輯頁面

點(diǎn)擊提交后可以多看到日志輸出


點(diǎn)擊提交日志輸出

碰到問題:沒有打印日志情況
log4j 設(shè)置日志輸出文件的路徑

log4j配置參數(shù)不要搞錯(cuò)

文件上傳Spring提供了一個(gè)bean:CommonsMultipartResolver

SpringMVC內(nèi)置了文件上傳功能,我們只需通過一些配置谜疤,就可以使用Spring給我們暴露的接口實(shí)現(xiàn)文件上傳
需要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對(duì)json的支持mvc-dispatcher-servlet.xml添加配置bean的ContentNegotiatingViewResolver類(后來發(fā)現(xiàn)這個(gè)配置已經(jīng)過時(shí)现诀,后面有問題描述及解決辦法)

    <!-- 配置ViewResolver。 可以用多個(gè)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 對(duì)json支持不能認(rèn)識(shí)

參考:

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錯(cuò)誤(Bean property 'mediaTypes' is not writable or has an invalid setter method.)

修改對(duì)mvc-dispatcher-servlet.xml對(duì)json的支持(同時(shí)記得刪除錯(cuò)誤的配置)

    <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數(shù)據(jù)

jsp對(duì)后臺(tái)請(qǐng)求的異步處理course_json.jsp (采用到的是jquery庫中的ajax異步訪問技術(shù)尺棋,記得如果有更換jquery版本要在這個(gè)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數(shù)據(jù)處理的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({  //調(diào)用jQuery中的ajax
        method: "GET", //才用get方式請(qǐng)求
        url: urlStr, //ajax 訪問web后端的地址
        success:function(data,status,jqXHR){//ajax拿到數(shù)據(jù)之后動(dòng)態(tài)加載dom的方式加載數(shù)據(jù)
            //alert("Success:"+data);
            var course = data;
            var path = "<%=request.getContextPath()%>/";    
            $(".course-title").html(course.title);//動(dòng)態(tài)加載dom的方式加載數(shù)據(jù)
            $(".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>學(xué)習(xí)人數(shù)</span> <em id="learningNum"></em></li>
                        <li class="course_hour"><span>課程時(shí)長(zhǎng)</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>

所以工作全部完成后目錄結(jié)構(gòu)

完成后的目錄結(jié)構(gòu)
Maven引入的內(nèi)容

下面把用到的代碼貼出來

代碼下載地址

https://yunpan.#/surl_yQXTvTU5vFb (提取碼:1a1c)

不錯(cuò)的源碼推薦:
Spring+SpringMvc+MyBatis+Redis基于SSM-EasyUI的權(quán)限管理系統(tǒng)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末封锉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膘螟,更是在濱河造成了極大的恐慌成福,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荆残,死亡現(xiàn)場(chǎng)離奇詭異奴艾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)脊阴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門握侧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嘿期,你說我怎么就攤上這事品擎。” “怎么了备徐?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵萄传,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蜜猾,道長(zhǎng)秀菱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任蹭睡,我火速辦了婚禮衍菱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肩豁。我一直安慰自己脊串,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布清钥。 她就那樣靜靜地躺著琼锋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祟昭。 梳的紋絲不亂的頭發(fā)上缕坎,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音篡悟,去河邊找鬼谜叹。 笑死匾寝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叉谜。 我是一名探鬼主播旗吁,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼停局!你這毒婦竟也來了很钓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤董栽,失蹤者是張志新(化名)和其女友劉穎码倦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锭碳,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袁稽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了擒抛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片推汽。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖歧沪,靈堂內(nèi)的尸體忽然破棺而出歹撒,到底是詐尸還是另有隱情,我是刑警寧澤诊胞,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布暖夭,位于F島的核電站,受9級(jí)特大地震影響撵孤,放射性物質(zhì)發(fā)生泄漏迈着。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一邪码、第九天 我趴在偏房一處隱蔽的房頂上張望裕菠。 院中可真熱鬧,春花似錦闭专、人聲如沸奴潘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至粪滤,卻和暖如春斧拍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背杖小。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工肆汹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留愚墓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓昂勉,卻偏偏與公主長(zhǎng)得像浪册,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岗照,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理村象,服務(wù)發(fā)現(xiàn),斷路器攒至,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,773評(píng)論 6 342
  • Spring MVC一厚者、什么是 Spring MVCSpring MVC 屬于 SpringFrameWork 的...
    任任任任師艷閱讀 3,374評(píng)論 0 32
  • 學(xué)習(xí)資料源:慕課網(wǎng) - Spring MVC起步 內(nèi)容概要 一、前端控制器(Front Controller) 二...
    拾壹北閱讀 1,958評(píng)論 0 22
  • 出發(fā)——嫵媚與呆萌 此時(shí)看到一個(gè)散落的城鎮(zhèn)的公路上正駛過一輛貼著“德臥-興義”的中巴迫吐。人們的房頂都建有太陽能熱水器...
    心靈復(fù)興閱讀 785評(píng)論 1 2