SpringMvc示例一:快速搭建springMVC应用

先来上一张SpringMVC处理请求全过程。

这里写图片描述

该图来自:http://jinnianshilongnian.iteye.com/blog/1594806
清晰的展示了从请求以响应spring在中间都做了些什么事情,感觉画得好就先放在这里了。

1、新建项目:myframework;

2、添加spring框架依赖jar包,为了简单我这里把所有依赖包都添加了到WEB-INF\lib目录下,另外还要添加一个三方包commons-logging-api-1.1.jar。准备工作完成,

3、在web.xml中添加DispatchServlet,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>myframework</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>dispatch</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 初始化参数 -->
        <init-param>
            <!-- 指明servlet配置文件位置,spring将从此位置载入spring容器 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>  
                /WEB-INF/classes/dispatch-servlet*.*  
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- 配置DispatcherServlet所需要拦截的 url -->
    <servlet-mapping>
        <servlet-name>dispatch</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

load-on-startup:表示启动容器时初始化该Servlet;
init-param:指明了dispatch这个servlet配置文件位置为: /WEB-INF/classes/dispatch-servlet*.* ,非必须的配置。
url-pattern:表示哪些请求交给Spring Web MVC处理, “/” 是用来定义默认servlet映射的。也可以如“.html”表示拦截所有以html为扩展名的请求,这里将拦截所有以.do接尾的请求。

自此请求已交给Spring Web MVC框架处理,我们还需要配置Spring的配置文件,若不配置init-param指定配置文件位置,将从默认位置WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml,加载配置文件。这里我指定了文件位置,所以将会从/WEB-INF/classes/dispatch-servlet*.* 加载。注意这里多加了一层classess目录

4、配置dispatch-servlet.xml,我的dispatch-servlet.xml源文件位置在src目录下,编译后文件位置在WEB-INF\classess目录下。内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  
                http://www.springframework.org/schema/aop  
                http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 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">
    <!-- 配置SpringMVC的视图渲染器, 让其前缀为:/ 后缀为.jsp 将视图渲染到/page/<method返回值>.jsp中 -->
    <beans:bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/pages/" p:suffix=".jsp">
    </beans:bean>
</beans:beans>  

5、创建Controller。

package com.ldz.demo.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class HelloController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
        // 创建模型跟视图,用于渲染页面。并且指定要返回的页面为hello页面,结合dispatch-servlet.xml中的配置,可知道最终返回页面为:/pages/hello.jsp
        ModelAndView mav = new ModelAndView("hello");
        return mav;
    }
}

进入一下步,将Controller类注册到dispatch-servlet.xml中,让spring容器进行管理。
6、在dispatch-servlet.xml中添加配置

<!--这里必须以.do接尾,否则报404错误,因为web.xml中配置了spring只拦截.do接尾的请求-->
<beans:bean name="/hello.do" class="com.ldz.demo.controller.HelloController" />

至此,springMVC基本架子已经搭建好了。发布到tomcat中,启动应用,访问:
http://localhost:8080/myframework/hello.do

应用目录结构图
这里写图片描述

一点说明:
仔细点可以看到dispatch-servlet.xml中每个结点都有<beans前缀。这样的写法不太符合平时的习惯,如果改成下面写法如何呢?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  
                http://www.springframework.org/schema/aop  
                http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 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">

    <!-- SpringMVC配置 -->

    <!-- 通过component-scan 让Spring扫描org.swinglife.controller下的所有的类,让Spring的代码注解生效 -->
    <!-- <context:component-scan base-package="com.ldz.demo.controller"></context:component-scan> -->
    <!-- 配置SpringMVC的视图渲染器, 让其前缀为:/ 后缀为.jsp 将视图渲染到/page/<method返回值>.jsp中 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/pages/" p:suffix=".jsp">
    </bean>
    <bean name="/hello.do" class="com.ldz.demo.controller.HelloController" />
</beans>  

去掉前缀后,启动时就报错了,提示找不到<beans的定义 ,那肯定就是引用的schema有问题,对比和以前项目文件后发现

<beans:beans xmlns="http://www.springframework.org/schema/mvc"

修改为下面schema后,就不需要beans前缀,而且也能正常启动了。

<beans xmlns="http://www.springframework.org/schema/beans"

Controller实现方式

实现一个Controller有很多种方式,特别在spring2.5以后支持注解后,大大的减化了xml配置的繁所工作。
出于学习目的先来了解2.5之前实现Controller的方法。
第一种,上文中提到的,从Controller类继承,只需要实现下面个方法就行了。

public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception;

实现代码

@Override
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// 创建模型跟视图,用于渲染页面。并且指定要返回的页面为home页面
ModelAndView mav = new ModelAndView(“hello”);
mav.addObject(“desc”, “HelloController!”);
return mav;
}

在dispatch-servlet.xml配置控件器

<bean name="/hello.do" class="com.ldz.demo.controller.HelloController" />

第二种,从AbstractController继承
实现代码

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// 创建模型跟视图,用于渲染页面。并且指定要返回的页面为home页面
ModelAndView mav = new ModelAndView(“hello”);
mav.addObject(“message”, “HiAbstractController!,这是一个从AbstractController继承的Controller”);
return mav;
}

在dispatch-servlet.xml配置控件器,

<bean name="/hi.do" class="com.ldz.demo.controller.HiAbstractController" />

响应方式

  • 返回ModelAndView或直接通过response写响应。像ajax请求时,不需要返回页面视图时,就通过response写响应,之后直接return null;告诉DispatchServlet已经自己返回数据,不需要进行视图渲染。
    代码实现:

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
    // 创建模型跟视图,用于渲染页面。并且指定要返回的页面为home页面
    arg1.setHeader(“Content-type”, “text/html;charset=UTF-8”);
    //这句话的意思,是告诉servlet用UTF-8转码,而不是用默认的ISO8859
    arg1.setCharacterEncoding(“UTF-8”);
    arg1.getWriter().write(“这句话是直接在Controller里面直接返回页面的!!”);
    // 如果想直接在该处理器/控制器写响应 可以通过返回null告诉DispatcherServlet自己已经写出响应了,不需要它进行视图解析
    return null;
    }

  • 在写响应之前,设置了响应头和字符编码,如果不写的话返回内容乱码。而且要写在方法最前面。对于编码设置,肯定有比这个现简单有效的办法,编码问题留到以后再来讲。

继承AbstractController其他可用参数设置

继承至AbstractController的控件器有以下属性可设置,继承至Controller的控制器没有这些属性。

1.强制请求方法类型,强制指定客户端请求时使用GET或POST请求类型,如登录、注册类请求强制使用POST方式提交数据。
在dispatch-servlet.xml中controller设置以下参数:

<bean name="/hi.do" class="com.ldz.demo.controller.HelloController">
<property name="supportedMethods" value="POST"></property>
</bean>

2.当前请求的session前置条件检查,如果当前请求无session将抛出HttpSessionRequiredException异常:

<bean name="/hi.do" class="com.ldz.demo.controller.HelloController">
<property name="requireSession" value="true"/>
</bean>

3.客户端端缓存控制

<bean name="/hi.do" class="com.ldz.demo.controller.HelloController">
<!-- value>0,数字表示缓存秒数 ,value=0:表示不缓存,value<0表示响应头什么缓存信息都不加。-->
<property name="cacheSeconds" value="5" />
</bean>

请求效果图,第一次从服务器返回,紧接第二次Size列显示(form cache)。说明是从缓存中获取请求数据。
这里写图片描述
这里写图片描述
注:下面提到一些关于缓存控制的一些特殊情况:
- 1. 对于一般的页面跳转(如超链接点击跳转、通过js调用window.open打开新页面都是会使用浏览器缓存的,在未过期情况下会直接使用浏览器缓存的副本,在未过期情况下一次请求也不发送);
- 2.对于刷新页面(如按F5键刷新),会再次发送一次请求到服务器;

4.Last-Modified缓存机制
在继承AbstractController类基础上再实现LastModified接口即可。

public long getLastModified(HttpServletRequest request) {
if(lastModified == 0L) {
//TODO 此处更新的条件:如果内容有更新,应该重新返回内容最新修改的时间戳
lastModified = System.currentTimeMillis();
}
return lastModified;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wolf犭良

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值