【SpringMVC】四、视图与RestFul案例

View视图

Thymeleaf视图

若没有前缀,则为Thymeleaf视图,若有forward:则为转发视图,若有Redirect:则为重定向视图。

当控制器方法中的视图没有任何前缀时,视图会被设置的配置文件中的视图解析器解析。

Forward转发视图

使用转发技术,在视图的返回值前加forward可以使请求转发给另一个请求,即调用另一个控制器方法。

    @RequestMapping (value = "/testForward")
    public String testForward () {
        //在视图的配置中,若要在一个控制器下调用另一个控制器(转发),就要利用转发技术forward
        //使用转发技术,使其调用另一个控制器
        //这个就不是ThymeleafView,而是转发视图
        //注意这里forward:后的数据必须转到请求,不能直接转到页面
        return "forward:/testThymeleafView";
    }

转发请求创建的视图为InternalResourceView,而什么前缀都不带的视图叫做ThymeleafView,重定向视图为redirectView

Redirect重定向视图

重定向视图在视图名称以redirect:为前缀,以redirect:为前缀的视图不会被Thymeleaf解析,而是将后面的信息解析,并以重定向的方式请求。

注:转发是由一次请求,第二次请求是在服务器内部发生的,地址栏不变。重定向是两次请求,第二次是自动访问的,地址栏会发生改变。转发过程中,只有一个请求,所以request域中的数据不会删除,但在重定向的过程中,request请求发生了两次,所以request域中存储的数据是不相同的。

    @RequestMapping (value = "/testRedirect")
    public String testRedirect () {
        return "redirect:/testThymeleafView";
    }

ViewController视图控制器

当Controller层不需要处理其他的请求,只需要返回最后的视图时,我们可以使用ViewController,即只需要设置视图名称,不需要进行其他操作的时候就可以使用这个控制器。

使用该控制器需要在SpringMVC中进行配置(注意命名空间):

<!-- path路径下就是@RequestMapping的value值,和前端匹配。 -->
<!-- view-name是return的返回值,也就是转到的页面 -->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>

这样配置之后就可以不写@RequestMapping实现一个只有请求功能,不带其他任何功能的Thymeleaf视图跳转。

但注意在进行这个配置之后,所有的Thymeleaf跳转都会失效(404),这时候必须开启MVC的注解驱动才可以让其他页面正常请求

Restful

Get:查询,Post:添加,Put:修改,Delete:删除

Restful提倡统一的设计风格,从前到后各个单词按斜线分开,不使用?作为请求参数的携带。

举例:

原来以不同的方法作为增删改查的四种不同功能,现在以四种不同的请求方式作为不同的功能,例如:

查询:

  • getUserById --> user/1(get请求方式)

  • saveUser --> user(post请求方式)

  • deleteUser --> user/1(delete请求方式)

  • updateUser --> user(put请求方式)

使用Restful实现用户的操作

使用restful风格实现查询操作:

    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public String getAllUsers() {
        System.out.println("假装我查询了所有信息");
        return "success";
    }

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public String getUserById () {
        System.out.println("根据用户id查询信息");
        return "success";
    }

前端:

  <a th:href="@{/users}">查询所有用户信息</a><br>
  <a th:href="@{/user/1}">根据id查询信息</a><br>

实现添加操作:

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String insertUser (String username, String password) {
        System.out.println("添加用户信息:" + username + " " + password);
        return "success";
    }

前端:

  <form th:action="@{/user}" method="post">
    用户名:<input type="text" name="username" /><br>
    密码:<input type="password" name="password" /><br>
    <input type="submit" value="添加信息"><br>
  </form>

但要以put和delete实现修改和删除操作时,不可以简单的使用form表单的put和delete请求,还要添加过滤器。

在web.xml文件中配置过滤器:

<!--    设置put和delete的hiddenHttpMethodFilter-->
    <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>

注:过滤器方法一定有参数FilterChain来确定是拦截还是放行

过滤器添加之后,在后端使用put方法。

    @RequestMapping (value = "/user", method = RequestMethod.PUT)
    public String updateUser (String username, String password) {
        System.out.println("修改用户信息:" + username + " " + password);
        return "success";
    }

在前端使用post方法并添加隐藏标签,隐藏标签的name必须设置为_method,其value值可以设为put或delete

  <form th:action="@{/user}" method="post">
<!--      将真正的请求方式传入,传入一个hidden的input标签,并将其命名为_method,令其value值为真正的请求(put或delete)-->
      <input type="hidden" name="_method" value="PUT">
    用户名:<input type="text" name="username" /><br>
    密码:<input type="password" name="password" /><br>
    <input type="submit" value="修改信息"><br>
  </form>

RestFul案例

环境配置

设置pom.xml

打包方式设置为war包,并添加依赖。

    <dependencies>
        <!-- SpringMVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.1</version>
        </dependency>

        <!-- 日志 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!-- ServletAPI -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Spring5和Thymeleaf整合包 -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.12.RELEASE</version>
        </dependency>
    </dependencies>

添加web.xml

在web.xml文件中配置两个过滤器和前端控制器

	<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--    设置编码过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--    设置put和delete的hiddenHttpMethodFilter-->
    <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>

    <!--    配置springMVC前端控制器DispatcherServlet-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--        不使用springMVC的默认配置文件,自己进行配置-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

在resources下添加springMVC.xml并进行配置(注意扫描组件的包名要随项目进行更改)、

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


<!--    扫描组件-->
    <context:component-scan base-package="改这个!!!!!!!!!!!,使用逗号隔开就可以写两个包"></context:component-scan>

<!--    配置Thymeleaf视图解析器-->
    <!--    配置视图解析器Thymeleaf-->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <!--        Thymeleaf优先级的配置-->
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <!--        模板-->
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">

                        <!-- 视图前缀 -->
                        <property name="prefix" value="/WEB-INF/templates/"/>

                        <!-- 视图后缀 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8" />
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
</beans>

首页的配置

因为首页只需要实现一个跳转的功能,故在springMVC.xml文件中直接进行首页的配置:

配置在beans标签下

<!--    配置视图控制器,即首页的跳转-->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>

<!--    避免视图控制器的配置影响到其他组件,开启mvc注解驱动-->
    <mvc:annotation-driven />

首页的html:

<body>
  <h1>首页</h1>
  <a th:href="@{/employee}">查看员工信息</a>
</body>

查看所有信息

后端配置(Controller):

    @Autowired
    private EmployeeDao employeeDao;

    @RequestMapping(value = "/employee", method = RequestMethod.GET)
    public String getAllEmployees (Model model) {
        Collection<Employee> employeeList = employeeDao.getAll();
        //向域中添加数据
        model.addAttribute("employeeList", employeeList);
        return "employee_list";
    }

前端配置:

<body>
  <table>
    <tr>
<!--      合并五行-->
      <th colspan="5">Employee Info</th>
    </tr>
    <tr>
      <th>id</th>
      <th>lastname</th>
      <th>email</th>
      <th>gender</th>
      <th>options</th>
    </tr>
<!--    循环集合-->
    <tr th:each="employee : ${employeeList}">
      <td th:text="${employee.id}"></td>
      <td th:text="${employee.lastName}"></td>
      <td th:text="${employee.email}"></td>
      <td th:text="${employee.gender}"></td>
      <td>
        <a href="">delete</a>
        <a href="">update</a>
      </td>
    </tr>
  </table>
</body>

删除

注意maven中打war包可能会发生类似于Cannot access defaults field of Properties这样的错误,一种解决方式为在POM.xml文件中的paoject标签内添加如下插件:

	<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
            </plugin>
        </plugins>
    </build>

再进行packaged就可以成功打包了

删除操作的具体操作

对删除的超链接进行点击事件的绑定并确定转到的Controller层方法

<a @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a>

设置表单来确定delete对应相应的Controller:

<!--  delete按钮来控制表单-->
    <form id="deleteForm" method="post">
        <input type="hidden" name="_method" value="delete" />
    </form>

在vue中确定click方法的内容:

    deleteEmployee : function (event) {
        //根据id获取表单元素
        var deleteForm = document.getElementById("deleteForm");
        //将点击事件的href赋值给表单的action
        deleteForm.action = event.target.href;
        //提交表单
        deleteForm.submit();
        //取消提交表单的默认行为
        //如果不取消,超链接会有默认行为,先跳转页面。
        event.preventDefault();
    }

后台的delete操作:

    @RequestMapping (value = "/employee/{id}", method = RequestMethod.DELETE)
    //@PathVariable注解将RequestMapping传进来的id赋值给形参id
    public String deleteEmployee(@PathVariable("id") Integer id) {
        employeeDao.delete(id);
        //因为最后要返回整个页面的请求,所以使用重定向,转发可能会重新读取导致删除看起来有问题
        return "redirect:/employee";
    }

Dao层的Delete操作:

//相当于从Map中删除了一条记录    
	public void delete(Integer id){
        employees.remove(id);
    }

修改

在首页面中进行操作:

将链接赋值:

<a th:href="@{'/employee/'+${employee.id}}">update</a>

跳转到后台Controller层的请求:

    //回显功能,使用Get方法
    @RequestMapping (value = "/employee/{id}", method = RequestMethod.GET)
    public String update(@PathVariable Integer id, Model model) {
        Employee emp = employeeDao.get(id);
        //添加到域中
        model.addAttribute("employee", emp);
        return "employee_update";
    }

请求跳转到employee_update.html页面

<body>
  <form th:action="@{/employee}" method="post">
<!--      解析实际的请求方式-->
      <input type="hidden" name="_method" value="put" />
      <input type="hidden" name="id" th:value="${employee.id}" />
      lastName:<input type="text" name="lastName" th:value="${employee.lastName}"/><br>
      email:<input type="text" name="email" th:value="${employee.email}"/><br>
<!--      使用th:field操作来对radio标签赋初值-->
      gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}"/>male
             <input type="radio" name="gender" value="0" th:field="${employee.gender}"/>female<br>
      <input type="submit" value="UPDATE"/>
  </form>

再响应到Controller层中的update方法

    @RequestMapping (value = "/employee", method = RequestMethod.PUT)
    public String updateEmployee(Employee emp) {
        employeeDao.save(emp);
        return "redirect:/employee";
    }

最终调用Dao层的方法对数据进行修改

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值