SpringMvc-restFul学习笔记

Spring RestFul

查询所有用户

@Controller
public class RestFulAction {
    @Resource(name="userDao")
    private IUserDao dao ;



    /**
     * 查询所有用户
     * @param request请求对象的attributeMap,键为属性名,值为属性值。
     * @return 跳转到list页面.jsp
     */
    @RequestMapping("/userList")
    public String list(Map<String,Object> map
            ){
        List<User> users = dao.getAllUser();
        map.put("users", users);
        return "list";
    }

添加功能的实现

/**
     * 注册用户功能输入页面的路径映射,因为跳转过去的user页面使用了form:标签,所以要从控制器跳转过去页面才不会出错
     * @param map 请求域对象属性Map
     * @return 跳转到注册页面user.jsp
     */
    @RequestMapping(value="/user",method=RequestMethod.GET)
    public String input(Map<String,Object> map){
        map.put("xx", "xx");
        map.put("user",new User());
        return "user";
    }

    /**
     * 注册页面输入框填写完毕后执行的用户添加到数据库的操作
     * @param u 从页面穿过来的包含了User对象各个属性值的参数
     * @return 添加成功,重定向到显示用户列表的控制器来跳转到list.jsp页面
     */

    @RequestMapping(value="/user",method=RequestMethod.POST)
    public String add(
            User u
            ){
        dao.addUser(u);
        return "redirect:/userList";
    }

RestFul删除

SpringMvc静态资源:

1.为什么会有这样的问题:
优雅的Rest风格的资源URL不希望带.html或者.do后缀,若将所有路径映射阻拦,包括静态资源,SpringMvc会将他们当成一个普通请求处理
所以要这么设置;当没有被spring映射当前请求,交给tomcat的defaultServlet来处理即可;

<!-- springMvc会判断是否被映射过,如果有映射过就给个回复,如果没有被映射过(静态资源),
    则就去调用tomcat默认的servlet,交由这个default,servlet来处理 default-servlet-name="default"
 这个方法主要是用来对付调用静态页面,例如js和html等
     -->
    <mvc:default-servlet-handler />
删除功能

由于一般只能接收Post和get请求,所以我们需要做一定的转换,讲post或者get转化成delete以及put等表单提交方式;特别是像删除功能,点击超链接来链接到服务器,但是由于==超链接==是get方法,所以我们需要进行一定的转化;
Spring Mvc里面给出的转换方法只有从Post转化到Delete或者Put,在web.xml配置下面一段;


  <!-- 配置HiddenHttpMethodFiter:把Post请求转为Delete,Put -->
    <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>

接下来的思路就是将get 请求转换成Post请求类型,所以我们要引入一个隐藏表单,表单里面的输入框的值就是要执行的方法;
==_method貌似是spring能识别的RequestMethod参数;==将这个值设置为Delete,则进行删除;
然后使用java script,点击超链接时提交这个表单


$(function(){
    $(".delete").click(function(){
     var href = $(this).attr("href")
     $("form").attr("action",href).submit()
     return false;
    });

});



    <form action="" method="post">
    <input type="hidden" name="_method" value="DELETE"/>
    </form>

<td><a class="delete" href="user/${u.id }">删除</a></td>

RestFul修改,表单回填思路

修改东西,则其实就相当于要重新输入一次对象的属性,那么就要到添加页面去执行操作,但是修改需要一个对象的id,所以如果用添加页面的路径映射则不能获取对象现有属性,所以要另外进行==输入页面==的映射,下面做一个添加页面和修改页面的输入路径映射的不同

添加功能的输入页面的映射
/**这个是添加页面,为什么要put一个对象进去呢,因为使用spring的form标签来输出jsp页面的话,需要设定一个modelAttribute表单属性
<form:form action="${pageContext.request.contextPath}/user" method="POST" modelAttribute="user">
那么这样做的表单就需要进入这个jsp页面时有对应的user所指的对象,并且在form表单里面使用的 form空间的path要和该对象的属性名称一致,不然会报错;
map.put("user",new User())相当于传一个空白对象模板过去让用户填写表单

*/
@RequestMapping(value="/user",method=RequestMethod.GET)
    public String input(Map<String,Object> map){
        map.put("xx", "xx");
        map.put("user",new User());
        return "user";
    }
修改功能的输入页面的映射
@RequestMapping(value="/user/{id}",method=RequestMethod.GET)
    public String updateInput(
            @PathVariable("id") int id,
            Map<String,Object> map
            ){
        map.put("user", dao.getUserById(id));
        return "user";
    }
修改页面输入完毕后执行修改操作方法
/**
     * 判断传过来的东西带不带id,如果带id的话就把页面穿过来的modelAttribute=user对应的对象根据id从数据库中查出来完整的数据
     * 就不用在表单域中把每个参数都写上来。
     * @param id 对象id
     * @param map 请求域map(也是modelAttribute对应的对象),将里面的对象属性使用dao作为原始数据,然后表单传过来的对象属性数据作为修改后的数据,
     * 于是在下列修改方法中得到的User u,基本属性是建立与这个u上面,把这个user作为原始数据,
     * 然后表单传过来的对象与原本有的u进行比较,看是否有变动的地方,如果有就进行修改,因为ModelAttribute定义在方法上,表名这个方法相当于init(),
     * 每个请求进来的时候先执行这个方法  * 
     * 
     * @RequestParam(value="id",required=false),这个是传参  当required为false 时  使用这个注解可以不传这个参数  true时必须
     */
    @ModelAttribute
    public void getUser(@RequestParam(value="id",required=false) Integer id,
            Map<String,Object> map
            ){
        if(id!=null){
            map.put("user", dao.getUserById(id));
            System.out.println("这里是初始化User方法:" + map.get("user"));
        }
    }

    /**
     * 修改属性页面填写完毕后所到达的方法,这里配合用ModelAttribute注解的getUser方法来完善穿过来的User 对象的属性,
     * @param u 表单提交上来要修改的对象属性,相当于执行了多次u.setXXX
     * @return
     */
    @RequestMapping(value="/user",method=RequestMethod.PUT)
    public String update(
            User u
            ){
        System.out.println("这里是修改方法:" + u);
        dao.updateUser(u);
        return "redirect:/userList";

    }

完整的web.xml

<?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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>springmvc</display-name>
  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

  <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:config/spring/spring*.xml</param-value>
    </init-param>
    <load-on-startup></load-on-startup>
  </servlet>
  <!-- 拦截了所有的uri,包括.js,.html,都当做spring请求来处理js.html称之为静态资源 -->
  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 配置HiddenHttpMethodFiter:把Post请求转为Delete,Put -->
    <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>
</web-app>

完整的Spring-core.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 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-3.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/mvc
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
     http://www.springframework.org/schema/tx   
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- 扫描spring注解 -->

    <context:component-scan base-package="com.wang"></context:component-scan>

    <!-- springMvc会判断是否被映射过,如果有映射过就给个回复,如果没有被映射过(静态资源),
    则就去调用tomcat默认的servlet,交由这个default,servlet来处理 default-servlet-name="default"

     -->
    <mvc:default-servlet-handler />
    <!-- MVC注解驱动,挂载自动转换器 -->
    <mvc:annotation-driven conversion-service="tcs"
        validator="localValidator" />

    <!-- 提供事务注解支持 -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!-- 配置 -->


    <!-- 读取硬盘上的项目目录中的配置文件 -->
    <bean
        class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:database.properties</value>
            </list>
        </property>
    </bean>

    <!-- 数据源(第三方dhcp数据源连接池) -->
    <bean id="dbcp_dateSource" class="org.apache.commons.dbcp.BasicDataSource">
        <!-- 通过${driver}获取配置信息,还需要从本地读取配置文件 -->
        <property name="driverClassName" value="${driver}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${username}"></property>
        <property name="password" value="${password}"></property>
        <property name="defaultAutoCommit" value="false"></property>
        <property name="initialSize" value="5"></property>
    </bean>

    <!-- 基于hibernate的Session工厂 -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <!-- 数据源,在这里使用了第三方的连接池当做数据源 ,该参考类要实现了sql.dateSource接口 -->
        <property name="dataSource" ref="dbcp_dateSource">
        </property>

        <!-- 将hibernate的设置参数引入Spring配置,如此就不用单独设置hibernate配置文件 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            </props>
        </property>

        <!-- 要扫描的包,导入包内注解好映射的实体类 -->
        <property name="packagesToScan" value="com.wang.model"></property>

    </bean>


    <!-- Hibernate事务管理器的配置 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>


    <!-- 日期转换器 -->
    <bean id="tcs"
        class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.wang.conversion.DateConverter">
                    <!-- set注入一个日期格式化工具 -->
                    <property name="sdf">
                        <!-- 该工具是一个SimpleDateFormat类 -->
                        <bean class="java.text.SimpleDateFormat">
                            <!-- 该格式化工具创建时使用构造器注入,加入格式 -->
                            <constructor-arg value="yyyy-MM-dd"></constructor-arg>
                        </bean>
                    </property>

                </bean>

                <!-- 另一种方法 <bean class="com.wang.conversion.DateConverter"> </bean> -->
            </list>
        </property>
    </bean>

    <!-- 验证器 -->
    <bean id="localValidator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="validationMessageSource" ref="messageSource"></property>
    </bean>

    <!-- 文件上传支持 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 文件最大大小byte -->
        <property name="maxUploadSize" value="10200000"></property>
    </bean>

    <!-- jsp参数配置 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 自定义全局异常处理 -->


    <!-- 国际化 -->

    <bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="res.app.app_res"></property>
    </bean>

</beans>

完整的一个RestFul风格增删改查Handle(也叫Action,Servlet)

package com.wang.action;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
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 com.wang.dao.IUserDao;
import com.wang.model.User;
@Controller
public class RestFulAction {
    @Resource(name="userDao")
    private IUserDao dao ;



    /**
     * 查询所有用户
     * @param request请求对象的attributeMap,键为属性名,值为属性值。
     * @return 跳转到list页面.jsp
     */
    @RequestMapping("/userList")
    public String list(Map<String,Object> map
            ){
        List<User> users = dao.getAllUser();
        map.put("users", users);
        return "list";
    }

    /**
     * 注册用户功能输入页面的路径映射,因为跳转过去的user页面使用了form:标签,所以要从控制器跳转过去页面才不会出错
     * @param map 请求域对象属性Map
     * @return 跳转到注册页面user.jsp
     */
    @RequestMapping(value="/user",method=RequestMethod.GET)
    public String input(Map<String,Object> map){
        map.put("xx", "xx");
        map.put("user",new User());
        return "user";
    }

    /**
     * 注册页面输入框填写完毕后执行的用户添加到数据库的操作
     * @param u 从页面穿过来的包含了User对象各个属性值的参数
     * @return 添加成功,重定向到显示用户列表的控制器来跳转到list.jsp页面
     */

    @RequestMapping(value="/user",method=RequestMethod.POST)
    public String add(
            User u
            ){
        dao.addUser(u);
        return "redirect:/userList";
    }

    /**
     * 删除功能的实现,只有_method参数为DELETE才能执行本方法
     * @param id 需要删除的对象id
     * @return 重定向到用户列表
     */

    @RequestMapping(value="/user/{id}",method=RequestMethod.DELETE)
    public String delete(
            @PathVariable("id") int                                                                           id
            ){
        dao.deleteUser(id);
        return "redirect:/userList";

    }


    /**
     * 从用户列表点击修改所去的填写修改属性的页面,但是由于页面不一定是每个属性都要修改,所以传过去的对象属性不一定全部都会取出来
     * @param id 绑定在超链接里面穿过来的id
     * @param map 请求域对象属性集合
     * @return 修改用户资料界面user.jsp,因为这个jsp页面使用了form:标签,所以实现了自动读取请求域中蕴含对象属性值的功能,表单回填的思路也基于此
     */
    @RequestMapping(value="/user/{id}",method=RequestMethod.GET)
    public String updateInput(
            @PathVariable("id") int id,
            Map<String,Object> map
            ){
        map.put("user", dao.getUserById(id));
        return "user";
    }




    /**
     * 判断传过来的东西带不带id,如果带id的话就把页面穿过来的modelAttribute=user对应的对象根据id从数据库中查出来完整的数据
     * 就不用在表单域中把每个参数都写上来。
     * @param id 对象id
     * @param map 请求域map(也是modelAttribute对应的对象),将里面的对象属性使用dao作为原始数据,然后表单传过来的对象属性数据作为修改后的数据,
     * 于是在下列修改方法中得到的User u,基本属性是建立与这个u上面,把这个user作为原始数据,
     * 然后表单传过来的对象与原本有的u进行比较,看是否有变动的地方,如果有就进行修改,因为ModelAttribute定义在方法上,表名这个方法相当于init(),
     * 每个请求进来的时候先执行这个方法  * 
     * 
     * @RequestParam(value="id",required=false),这个是传参  当required为false 时  使用这个注解可以不传这个参数  true时必须
     */
    @ModelAttribute
    public void getUser(@RequestParam(value="id",required=false) Integer id,
            Map<String,Object> map
            ){
        if(id!=null){
            map.put("user", dao.getUserById(id));
            System.out.println("这里是初始化方法:" + map.get("user"));
        }
    }

    /**
     * 修改属性页面填写完毕后所到达的方法,这里配合用ModelAttribute注解的getUser方法来完善穿过来的User 对象的属性,
     * @param u 表单提交上来要修改的对象属性,相当于执行了多次u.setXXX
     * @return
     */
    @RequestMapping(value="/user",method=RequestMethod.PUT)
    public String update(
            User u
            ){
        System.out.println("这里是修改方法:" + u);
        dao.updateUser(u);
        return "redirect:/userList";

    }
}

完整的一个 注册,修改用户的form标签的使用页面

<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!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>Insert title here</title>
</head>
<body>

<!-- 1.why使用form标签
    可以更快速的开发出表单页面,而且可以更方便的进行表单的回显;

    2:可以通过modelAttrbute属性制定绑定的模型属性,
    若没有制定该属性,则默认从request对象中读取command的表单bean
    如果该属性值也不存在,则会发生错误

    3modelAttribute和map里面放的"user"一致,必须存在这么一个对象

    如果有跨对象,对象里面嵌套对象,可以这样写,user.deparment.id
  -->


<form:form action="${pageContext.request.contextPath}/user" method="POST" modelAttribute="user">
    <!-- path属性对应html表单的标签的name属性值 -->

    <c:if test="${user.id == null }">
    登录名<form:input path="name"  
    /><br>
    </c:if>
    <c:if test="${user.id != null }">
        <form:hidden path="id"/>

        <!-- 为什么不用form标签的hidden,因为modelAttrbibute对应的对象中没有_method这个属性 -->
        <input type="hidden" name="_method" value="PUT"> 
    </c:if>
    密码<form:input path="password"/><br>
    生日<form:input path="birthday"/><br>
    <%
        Map<String,String> gender = new HashMap();
        gender.put("1", "男");
        gender.put("0","女"); 
        request.setAttribute("sex", gender);
    %>

    <!-- delimiter表示分隔符,可以用"<br>"来换行 -->
    性别<form:radiobuttons path="sex" items="${sex}"/><br>

    <!-- 下拉列表 注意,使用了form:标签,注释的话也会来识别你注释的代码是不是有写错了。
    <form:select path="department.id" items="${departments }" itemLabel="departmentName" itemValue="id">
    </select>   
    -->
    <input type="submit" value="提交"> 
</form:form>

</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值