继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

SpringMVC从入门到精通之第五章

HansonQ
关注TA
已关注
手记 21
粉丝 334
获赞 3452

上一章节主要讲了@Controller和@RequestMapping注解。
这一章想讲解另一个比较重要的注解(@PathVariable),因为这个注解支持现在当下较为流行的Restful风格的URL。
先说说这个注解的作用,支持将url中的占\位符参数绑定到目标方法的参数上, 该功能也是springmvc实现Restful风格url的重要措施。
既然说道了restful风格的url就不得不说一说什么是restful风格的URL?解决方式-->百度
在讲解用springmvc来实现restful请求之前先看看rest请求样子,restful风格的url的请求是不会有.do,action等结尾的请求(这就是”逼格“用的好能够提高网站性能,用的不好我就呵呵了,,其实你观看本文章的时候注意地址栏的这个链接就是restful风格的,这个足以说明rest使用的流行程度)。
它的风格应该类似这样:

/user:新增(POST请求)、
/user/1:修改(PUT请求)、
/user/1:删除(DELETE请求)、
/user/1:获取(GET请求)

我们熟悉的请求应该是POST和GET请求,这两个请求也是最常用的而实际上HTTP1.1请求还有PUT、DELETE等8种来表名请求的动作。
说了一堆,肯定有小伙伴等不及了,怎么还不说实现方式?
下面我们就来一步一步来用springmvc实现restful风格的请求。
还记得第二章中配置的web.xml么?
现在要实现restful风格的请求,当然离不开前端控制器要拦截的请求了。下面看配置

<!-- 配置前端控制器 -->
    <servlet>
        <servlet-name>springmvc-1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:mvc-dispatcher-servlet.xml</param-value>
        </init-param>
        <!-- 表示随WEB服务器启动 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 备注:可以拦截三种请求
         第一种:拦截固定后缀的url,比如设置为 *.do、*.action, 例如:/user/add.action此方法最简单,不会导致静态资源(jpg,js,css)被拦截. 
         第二种:拦截所有,设置为/,例如:/user/add /user/add.action此方法可以实现REST风格的url,很多互联网类型的应用使用这种方式.但是此方法会导致静态文件(jpg,js,css)被拦截后不能正常显示.需要特殊处理.
            1>.为什么会有静态资源问题
                优雅的REST 风格的资源URL 不希望带.html或.do等后缀
                若将DispatcherServlet请求映射配置为(第二种方式),则springmvc将捕获WEB容器所有请求,包括静态资源的请求,springmvc会将他们当成一个普通请求处理
                因为找不到对应处理器将导致错误。
            2>. 解决方案:
                可以在springmvc的配置文件中配置<mvc:default-servlet-handler/>的方式解决静态资源的问题。
                    1.>.<mvc:default-servlet-handler/>将在springmvc上下文中定义一个DefaultServletHttpRequestHandler,它会对进入DispatcherServlet的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由WEN应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet处理。
                    2.>.一般WEB应用服务器默认的Servlet的名称都是default,若所使用的WEB服务器的默认Servlet名称不是default,则需要通过default-servlet-name属性显示指定
             第三种:拦截所有,设置为/*,此设置方法错误,因为请求到Action,当action转到jsp时再次被拦截,提示不能根据jsp路径mapping成功. 
         -->
        <url-pattern>/</url-pattern>

注意一下配置里面的注释。
下面我们来看下实现get和post请求因为这两个请求比较常见!对熟人下手,速度较快
上面说道@PathVariable这个注解能够将url中的占_位符参数绑定到目标方法的参数上。
我们先看下实现页面:

<a href="${pageContext.request.contextPath}/springmvc/testRestfulGet/1">@PathVariable注解知识点:支持Restful风格的GET请求</a>
        <form action="${pageContext.request.contextPath}/springmvc/testRestfulPost" method="post">
        用户:<input type="text" name="username"/>
                密码:<input type="password" name="password"/><br>
        <input type="sumit" value="@PathVariable注解知识点:支持Restful风格的POST请求"/>
    </form>

后台处理器代码:

    /**
     * 
     * @Title: testRestfulGet
     * @Description: TODO (测试Restful风格的URL:GET请求)
     * @Author: Hanson                
     * @Create Date: 2016年1月27日 下午8:48:39
     * @History: 2016年1月27日 下午8:48:39 Hanson Created.
     *
     * @param id
     * @return
     *
     */
    @RequestMapping(value = "/testRestfulGet/{id}", method = { RequestMethod.GET })
    public String testRestfulGet(@PathVariable("id") Integer id) {
    System.out.println("The value which the restful style url is GET :"+ id);
        return "success";
    }

    /**
     * 
     * @Title: testRestfulPost
     * @Description: TODO (测试Restful风格的URL:POST请求)
     * @Author: Hanson                
     * @Create Date: 2016年1月27日 下午8:48:53
     * @History: 2016年1月27日 下午8:48:53 Hanson Created.
     *
     * @return
     *
     */
    @RequestMapping(value = "/testRestfulPost", method = { RequestMethod.POST })
    public String testRestfulPost() {
        System.out.println("The value which the restful style url is POST ");
        return "success";
    }

来看下这个注解的源码:

/**
 * Annotation which indicates that a method parameter should be bound to a URI template
 * variable. Supported for {@link RequestMapping} annotated handler methods in Servlet
 * environments.
 *
 * @author Arjen Poutsma
 * @see RequestMapping
 * @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
 * @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
 * @since 3.0
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {

    /** The URI template variable to bind to. */
    String value() default "";

}

上面英文大概意思就是:表明一个方法参数应该被绑定到一个URI模板的占位符中。
这个注解只有一个某人的value属性因此在使用的时候可以省略value="";(不太懂注解原理的童鞋可以去慕课网看看注解相关的教程)。
实现了GET和POST请求,下面就是这片文章的硬菜。
在springmvc中要实现PUT和DELETE 请求需要在web.xml额外配置一个过滤器,这个过滤器的作用就是把POST请求变为PUT和DELETE请求。
先看配置:

<!--org.springframework.web.filter.HiddenHttpMethodFilter:可以把Post请求转变为put和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>

这个类的一部分源码:

public class HiddenHttpMethodFilter extends OncePerRequestFilter {

    /** Default method parameter: <code>_method</code> */
    public static final String DEFAULT_METHOD_PARAM = "_method";

    private String methodParam = DEFAULT_METHOD_PARAM;

    /**
     * Set the parameter name to look for HTTP methods.
     * @see #DEFAULT_METHOD_PARAM
     */
    public void setMethodParam(String methodParam) {
        Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }

这个源码要求在提交POST请求的时候,需要隐藏一个属性名为“_method”,它的值可以是PUT或者DELETE等。
PUT请求和DELETE请求的JSP中实现代码如下:

<form action="${pageContext.request.contextPath}/springmvc/testRestfulDelete/1" method="post">
        <input type="hidden" name="_method" value="DELETE"/>
        用户:<input type="text" name="username"/>
                密码:<input type="password" name="password"/><br>
        <input type="sumit" value="@PathVariable注解知识点:支持Restful风格的DELETE请求"/>
    </form>
    <form action="${pageContext.request.contextPath}/springmvc/testRestfulPut/1" method="post">
        <input type="hidden" name="_method" value="PUT"/>
        用户:<input type="text" name="username"/>
                密码:<input type="password" name="password"/><br>
        <input type="submit" value="@PathVariable注解知识点:支持Restful风格的PUT请求"/>
    </form>

后台实现代码:

    /**
     * 
     * @Title: testRestfulDelete
     * @Description: TODO (测试Restful风格的URL:DELETE请求)
     * @Author: Hanson                
     * @Create Date: 2016年1月27日 下午9:07:20
     * @History: 2016年1月27日 下午9:07:20 Hanson Created.
     *
     * @param id
     * @return
     *
     */
    @RequestMapping(value = "/testRestfulDelete/{id}", method = { RequestMethod.DELETE })
    public String testRestfulDelete(@PathVariable("id") Integer id) {
    System.out.println("The value which the restful style url is DELETE :"+ id);
        return "success";
    }

    /**
     * 
     * @Title: testRestfulPut
     * @Description: TODO (测试Restful风格的URL:PUT请求)
     * @Author: Hanson                
     * @Create Date: 2016年1月27日 下午9:07:29
     * @History: 2016年1月27日 下午9:07:29 Hanson Created.
     *
     * @param id
     * @return
     *
     */
    @RequestMapping(value = "/testRestfulPut/{id}", method = { RequestMethod.PUT })
    public String testRestfulPut(@PathVariable("id") Integer id) {
    System.out.println("The value which the restful style url is PUT :"+ id);
        return "success";
    }

到这里这个注解就算学完了。
那么现在开始总结:看完这片文章应该什么是Rest请求?知道springmvc支持rest风格的请求、要支持这种优雅的请求要怎么配置。

打开App,阅读手记
24人推荐
发表评论
随时随地看视频慕课网APP

热门评论

@PathVariable注解省略能自动映射吗

put、delete等请求不是默认支持的么,我项目没配置也能用;不过网上说旧浏览器不支持,就需要使用post方式去模拟;初学,看晕头了

楼主,那个 “put” 和 “delete”,仅仅是用来区分是哪个post请求吗? 没有别的用处?

查看全部评论