史上最全最强SpringMVC详细示例实战教程

来源:互联网 发布:淘宝上正品金丝楠木店 编辑:程序博客网 时间:2024/04/30 11:39

一、SpringMVC基础入门,创建一个HelloWorld程序

  1.首先,导入SpringMVC需要的jar包。

  2.添加Web.xml配置文件中关于SpringMVC的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--configure the setting of springmvcDispatcherServlet and configure the mapping-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:springmvc-servlet.xml</param-value>
      </init-param>
      <!-- <load-on-startup>1</load-on-startup> -->
</servlet>
 
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

  3.在src下添加springmvc-servlet.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="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.xsd
        http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">                   
 
    <!-- scan the package and the sub package -->
    <context:component-scanbase-package="test.SpringMVC"/>
 
    <!-- don't handle the static resource -->
    <mvc:default-servlet-handler/>
 
    <!-- if you use annotation you must configure following setting -->
    <mvc:annotation-driven/>
     
    <!-- configure the InternalResourceViewResolver -->
    <beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"
            id="internalResourceViewResolver">
        <!-- 前缀 -->
        <propertyname="prefix"value="/WEB-INF/jsp/"/>
        <!-- 后缀 -->
        <propertyname="suffix"value=".jsp"/>
    </bean>
</beans>

  4.在WEB-INF文件夹下创建名为jsp的文件夹,用来存放jsp视图。创建一个hello.jsp,在body中添加“Hello World”。

  5.建立包及Controller,如下所示

  6.编写Controller代码

1
2
3
4
5
6
7
8
9
@Controller
@RequestMapping("/mvc")
publicclassmvcController {
 
    @RequestMapping("/hello")
    publicString hello(){       
        return"hello";
    }
}

  7.启动服务器,键入 http://localhost:8080/项目名/mvc/hello

 二、配置解析

  1.Dispatcherservlet

  DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。

  2.InternalResourceViewResolver

  视图名称解析器

  3.以上出现的注解

  @Controller 负责注册一个bean 到spring 上下文中

  @RequestMapping 注解为控制器指定可以处理哪些 URL 请求

 三、SpringMVC常用注解

  @Controller

  负责注册一个bean 到spring 上下文中

  @RequestMapping

  注解为控制器指定可以处理哪些 URL 请求

  @RequestBody

  该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上

  @ResponseBody

  该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区

  @ModelAttribute    

  在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法

  在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中 

  @RequestParam 

  在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法

  @PathVariable

  绑定 URL 占位符到入参

  @ExceptionHandler

  注解到方法上,出现异常时会执行该方法

  @ControllerAdvice

  使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常

 四、自动匹配参数

1
2
3
4
5
6
//match automatically
@RequestMapping("/person")
publicString toPerson(String name,doubleage){
    System.out.println(name+" "+age);
    return"hello";
}

 五、自动装箱

  1.编写一个Person实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
packagetest.SpringMVC.model;
 
publicclassPerson {
    publicString getName() {
        returnname;
    }
    publicvoidsetName(String name) {
        this.name = name;
    }
    publicintgetAge() {
        returnage;
    }
    publicvoidsetAge(intage) {
        this.age = age;
    }
    privateString name;
    privateintage;
     
}

  2.在Controller里编写方法

1
2
3
4
5
6
//boxing automatically
@RequestMapping("/person1")
publicString toPerson(Person p){
    System.out.println(p.getName()+" "+p.getAge());
    return"hello";
}

 六、使用InitBinder来处理Date类型的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
//the parameter was converted in initBinder
@RequestMapping("/date")
publicString date(Date date){
    System.out.println(date);
    return"hello";
}
    
//At the time of initialization,convert the type "String" to type "date"
@InitBinder
publicvoidinitBinder(ServletRequestDataBinder binder){
    binder.registerCustomEditor(Date.class,newCustomDateEditor(newSimpleDateFormat("yyyy-MM-dd"),
            true));
}

 七、向前台传递参数

1
2
3
4
5
6
7
8
9
//pass the parameters to front-end
@RequestMapping("/show")
publicString showPerson(Map<String,Object> map){
    Person p =newPerson();
    map.put("p", p);
    p.setAge(20);
    p.setName("jayjay");
    return"show";
}

  前台可在Request域中取到"p"

 八、使用Ajax调用

1
2
3
4
5
6
7
8
9
//pass the parameters to front-end using ajax
@RequestMapping("/getPerson")
publicvoidgetPerson(String name,PrintWriter pw){
    pw.write("hello,"+name);       
}
@RequestMapping("/name")
publicString sayHello(){
    return"name";
}

  前台用下面的jQuery代码调用

1
2
3
4
5
6
7
$(function(){
    $("#btn").click(function(){
       $.post("mvc/getPerson",{name:$("#name").val()},function(data){
            alert(data);
        });
    });
});

 九、在Controller中使用redirect方式处理请求

1
2
3
4
5
//redirect
@RequestMapping("/redirect")
publicString redirect(){
    return"redirect:hello";
}

 十、文件上传

  1.需要导入两个jar包

  2.在SpringMVC配置文件中加入

1
2
3
4
<!-- upload settings -->
<beanid="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <propertyname="maxUploadSize"value="102400000"></property>
</bean>

  3.方法代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RequestMapping(value="/upload",method=RequestMethod.POST)
publicString upload(HttpServletRequest req) throwsException{
    MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)req;
    MultipartFile file = mreq.getFile("file");
    String fileName = file.getOriginalFilename();
    SimpleDateFormat sdf = newSimpleDateFormat("yyyyMMddHHmmss");       
    FileOutputStream fos = newFileOutputStream(req.getSession().getServletContext().getRealPath("/")+
            "upload/"+sdf.format(newDate())+fileName.substring(fileName.lastIndexOf('.')));
    fos.write(file.getBytes());
    fos.flush();
    fos.close();
     
    return"hello";
}

  4.前台form表单

1
2
3
4
<formaction="mvc/upload"method="post"enctype="multipart/form-data">
    <inputtype="file"name="file"><br>
    <inputtype="submit"value="submit">
</form>

 十一、使用@RequestParam注解指定参数的name

1
2
3
4
5
6
7
8
9
10
@Controller
@RequestMapping("/test")
publicclassmvcController1 {
    @RequestMapping(value="/param")
    publicString testRequestParam(@RequestParam(value="id") Integer id,
            @RequestParam(value="name")String name){
        System.out.println(id+" "+name);
        return"/hello";
    }   
}

 十二、RESTFul风格的SringMVC

  1.RestController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Controller
@RequestMapping("/rest")
publicclassRestController {
    @RequestMapping(value="/user/{id}",method=RequestMethod.GET)
    publicString get(@PathVariable("id") Integer id){
        System.out.println("get"+id);
        return"/hello";
    }
     
    @RequestMapping(value="/user/{id}",method=RequestMethod.POST)
    publicString post(@PathVariable("id") Integer id){
        System.out.println("post"+id);
        return"/hello";
    }
     
    @RequestMapping(value="/user/{id}",method=RequestMethod.PUT)
    publicString put(@PathVariable("id") Integer id){
        System.out.println("put"+id);
        return"/hello";
    }
     
    @RequestMapping(value="/user/{id}",method=RequestMethod.DELETE)
    publicString delete(@PathVariable("id") Integer id){
        System.out.println("delete"+id);
        return"/hello";
    }
     
}

  2.form表单发送put和delete请求

  在web.xml中配置

1
2
3
4
5
6
7
8
9
<!-- configure the HiddenHttpMethodFilter,convert the post method to put or delete -->
<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  在前台可以用以下代码产生请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<formaction="rest/user/1"method="post">
    <inputtype="hidden"name="_method"value="PUT">
    <inputtype="submit"value="put">
</form>
 
<formaction="rest/user/1"method="post">
    <inputtype="submit"value="post">
</form>
 
<formaction="rest/user/1"method="get">
    <inputtype="submit"value="get">
</form>
 
<formaction="rest/user/1"method="post">
    <inputtype="hidden"name="_method"value="DELETE">
    <inputtype="submit"value="delete">
</form>

 十三、返回json格式的字符串

  1.导入以下jar包

  2.方法代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Controller
@RequestMapping("/json")
publicclassjsonController {
     
    @ResponseBody
    @RequestMapping("/user")
    public User get(){
        User u = newUser();
        u.setId(1);
        u.setName("jayjay");
        u.setBirth(newDate());
        returnu;
    }
}

 十四、异常的处理

  1.处理局部异常(Controller内)

1
2
3
4
5
6
7
8
9
10
11
12
13
@ExceptionHandler
publicModelAndView exceptionHandler(Exception ex){
    ModelAndView mv = newModelAndView("error");
    mv.addObject("exception", ex);
    System.out.println("in testExceptionHandler");
    returnmv;
}
    
@RequestMapping("/error")
publicString error(){
    inti = 5/0;
    return"hello";
}

  2.处理全局异常(所有Controller)

1
2
3
4
5
6
7
8
9
10
@ControllerAdvice
publicclasstestControllerAdvice {
    @ExceptionHandler
    publicModelAndView exceptionHandler(Exception ex){
        ModelAndView mv = newModelAndView("error");
        mv.addObject("exception", ex);
        System.out.println("in testControllerAdvice");
        returnmv;
    }
}

  3.另一种处理全局异常的方法

  在SpringMVC配置文件中配置

1
2
3
4
5
6
7
8
<!-- configure SimpleMappingExceptionResolver -->
<beanclass="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <propertyname="exceptionMappings">
        <props>
            <propkey="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
</bean>

  error是出错页面

 十五、设置一个自定义拦截器

  1.创建一个MyInterceptor类,并实现HandlerInterceptor接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
publicclassMyInterceptor implementsHandlerInterceptor {
 
    @Override
    publicvoidafterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throwsException {
        System.out.println("afterCompletion");
    }
 
    @Override
    publicvoidpostHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throwsException {
        System.out.println("postHandle");
    }
 
    @Override
    publicbooleanpreHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throwsException {
        System.out.println("preHandle");
        returntrue;
    }
 
}

  2.在SpringMVC的配置文件中配置

1
2
3
4
5
6
7
<!-- interceptor setting -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mappingpath="/mvc/**"/>
        <beanclass="test.SpringMVC.Interceptor.MyInterceptor"></bean>
    </mvc:interceptor>       
</mvc:interceptors>

  3.拦截器执行顺序

 十六、表单的验证(使用Hibernate-validate)及国际化

  1.导入hibernate-validate需要的jar包

(未选中不用导入)

  2.编写实体类User并加上验证注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
publicclassUser {
    publicintgetId() {
        returnid;
    }
    publicvoidsetId(intid) {
        this.id = id;
    }
    publicString getName() {
        returnname;
    }
    publicvoidsetName(String name) {
        this.name = name;
    }
    publicDate getBirth() {
        returnbirth;
    }
    publicvoidsetBirth(Date birth) {
        this.birth = birth;
    }
    @Override
    publicString toString() {
        return"User [id=" + id + ", name=" + name + ", birth=" + birth + "]";
    }   
    privateintid;
    @NotEmpty
    privateString name;
 
    @Past
    @DateTimeFormat(pattern="yyyy-MM-dd")
    privateDate birth;
}

  ps:@Past表示时间必须是一个过去值

  3.在jsp中使用SpringMVC的form表单

1
2
3
4
5
6
<form:formaction="form/add"method="post"modelAttribute="user">
    id:<form:inputpath="id"/><form:errorspath="id"/><br>
    name:<form:inputpath="name"/><form:errorspath="name"/><br>
    birth:<form:inputpath="birth"/><form:errorspath="birth"/>
    <inputtype="submit"value="submit">
</form:form>

  ps:path对应name

  4.Controller中代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Controller
@RequestMapping("/form")
publicclassformController {
    @RequestMapping(value="/add",method=RequestMethod.POST)   
    publicString add(@ValidUser u,BindingResult br){
        if(br.getErrorCount()>0){           
            return"addUser";
        }
        return"showUser";
    }
     
    @RequestMapping(value="/add",method=RequestMethod.GET)
    publicString add(Map<String,Object> map){
        map.put("user",newUser());
        return"addUser";
    }
}

  ps:

  1.因为jsp中使用了modelAttribute属性,所以必须在request域中有一个"user".

  2.@Valid 表示按照在实体上标记的注解验证参数

  3.返回到原页面错误信息回回显,表单也会回显

  5.错误信息自定义

  在src目录下添加locale.properties

NotEmpty.user.name=name can't not be emptyPast.user.birth=birth should be a past valueDateTimeFormat.user.birth=the format of input is wrongtypeMismatch.user.birth=the format of input is wrongtypeMismatch.user.id=the format of input is wrong

  在SpringMVC配置文件中配置

1
2
3
4
<!-- configure the locale resource -->
<beanid="messageSource"class="org.springframework.context.support.ResourceBundleMessageSource">
    <propertyname="basename"value="locale"></property>
</bean>

  6.国际化显示

  在src下添加locale_zh_CN.properties

username=账号password=密码

  locale.properties中添加

username=user namepassword=password

  创建一个locale.jsp

1
2
3
4
<body>
  <fmt:messagekey="username"></fmt:message>
  <fmt:messagekey="password"></fmt:message>
</body>

  在SpringMVC中配置

1
2
<!-- make the jsp page can be visited -->
<mvc:view-controllerpath="/locale"view-name="locale"/>

  让locale.jsp在WEB-INF下也能直接访问

  最后,访问locale.jsp,切换浏览器语言,能看到账号和密码的语言也切换了

 十七、压轴大戏--整合SpringIOC和SpringMVC

  1.创建一个test.SpringMVC.integrate的包用来演示整合,并创建各类

  2.User实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
publicclassUser {
    publicintgetId() {
        returnid;
    }
    publicvoidsetId(intid) {
        this.id = id;
    }
    publicString getName() {
        returnname;
    }
    publicvoidsetName(String name) {
        this.name = name;
    }
    publicDate getBirth() {
        returnbirth;
    }
    publicvoidsetBirth(Date birth) {
        this.birth = birth;
    }
    @Override
    publicString toString() {
        return"User [id=" + id + ", name=" + name + ", birth=" + birth + "]";
    }   
    privateintid;
    @NotEmpty
    privateString name;
 
    @Past
    @DateTimeFormat(pattern="yyyy-MM-dd")
    privateDate birth;
}

  3.UserService类

1
2
3
4
5
6
7
8
9
10
@Component
publicclassUserService {
    publicUserService(){
        System.out.println("UserService Constructor...\n\n\n\n\n\n");
    }
     
    publicvoidsave(){
        System.out.println("save");
    }
}

  4.UserController

1
2
3
4
5
6
7
8
9
10
11
12
13
@Controller
@RequestMapping("/integrate")
publicclassUserController {
    @Autowired
    privateUserService userService;
     
    @RequestMapping("/user")
    publicString saveUser(@RequestBody@ModelAttributeUser u){
        System.out.println(u);
        userService.save();
        return"hello";
    }
}

  5.Spring配置文件

  在src目录下创建SpringIOC的配置文件applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        "
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"   
        >
    <context:component-scanbase-package="test.SpringMVC.integrate">
        <context:exclude-filtertype="annotation"
            expression="org.springframework.stereotype.Controller"/>
        <context:exclude-filtertype="annotation"
            expression="org.springframework.web.bind.annotation.ControllerAdvice"/>       
    </context:component-scan>
     
</beans>

  在Web.xml中添加配置

1
2
3
4
5
6
7
8
<!-- configure the springIOC -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param
  <param-name>contextConfigLocation</param-name
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>

  6.在SpringMVC中进行一些配置,防止SpringMVC和SpringIOC对同一个对象的管理重合

1
2
3
4
5
6
7
<!-- scan the package and the sub package -->
    <context:component-scanbase-package="test.SpringMVC.integrate">
        <context:include-filtertype="annotation"
            expression="org.springframework.stereotype.Controller"/>
        <context:include-filtertype="annotation"
            expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>

 十八、SpringMVC详细运行流程图

 十九、SpringMVC与struts2的区别

  1、springmvc基于方法开发的,struts2基于类开发的。springmvc将url和controller里的方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。方法执行结束,形参数据销毁。springmvc的controller开发类似web service开发。

  2、springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。

  3、经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 科三考4次不过怎么办 科三挂了4次怎么办 征信进入黑名单怎么办 年检换标过期怎么办 滴滴叫不到车怎么办 学时卡丢了怎么办 驾校学员丢了怎么办 考驾照学时不够怎么办 车辆年审超时间怎么办 车辆过年检了怎么办 开公司货车违章怎么办 毕业证丢了怎么办居住证 贴吧回帖被秒删怎么办 群拉人失败了怎么办 安装解释包错误怎么办 皮皮麻将进不去怎么办 郑州集体户口怎么办准生证 广州集体户口准生证怎么办 学校寄档案丢失怎么办 深圳通儿童卡怎么办 集体户没有户口卡怎么办 北京滴滴跑长途怎么办 应届毕业生落户成都档案怎么办 执业医师缺考怎么办 国家级考试缺考怎么办 异地就业后档案怎么办 没有工作报到证怎么办 网络系统管理员封锁网络怎么办 公房没买断产权怎么办 去异地工作社保怎么办 深圳辞职了 社保怎么办 小产权孩子上学怎么办 多余的粽叶怎么办 农村两处宅基地怎么办 农村一户多宅怎么办 无锡未满五年安置房怎么办 人才公寓退休后怎么办 套餐到期不用了怎么办 日本手机自动续约怎么办 如果购房后退房怎么办 土地权70年到期怎么办