03、SpirngMVC核心(下)

一、关于RESTful编程风格

什么是RESTful

RESTful的英文全称是:Representational State Transfer(表述性状态转移)

RESTful是Web服务接口的一种设计风格。它定了一组约束和规范,可以让Web服务接口更加简洁、易于理解、易于扩展、安全可靠。

RESTful对于请求的约束如下:

  • 查询:发送GET请求
  • 新增:发送POST请求
  • 修改:发送PUT请求
  • 删除:发送DELETE请求

RESTful对于URL的约束如下:

  • 传统的get请求:/springmvc/getUserById?id=1,RESTful风格的url为:get请求 /springmvc/user/1
  • 传统的get请求:/springmvc/deleteUserById?id=1,RESTful风格的url为:delete请求/springmvc/user/1

RESTful对URL的约束和规范的核心是:通过 请求方式 + URL 确定web服务中的资源。

我们看一下RESTful与传统方式的URL对比

传统URL RESTful URL
GET /getUserById?id=1 GET /user/1
GEt /getAllUser GET /user
POST /addUser POST /user
POST /modifyUser PUT /user
GET /deleteUserById?id=1 DELETE /user/1

从上面可以看出来,传统的URL是基于动作的,而RESTful是基于资源与状态的。

RESTful - 查询

根据id查询

<!-- 根据id查询:GET /api/user/1 -->
<a th:href="@{/api/user/1}">根据id查询用户信息</a><br>
@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET)
public String getById(@PathVariable("id") Integer id) {
    System.out.println("根据用户id查询用户信息...用户的id是:" + id);
    return "ok";
}

后端接口中{id}表示一个路径占位符,参数要对应接收的时候使用@PathVariable注解放到对应的参数前。

查询所有

<!-- 查询所有用户信息 GET /api/user -->
<a th:href="@{/api/user}">查询所有用户信息</a><br>
@RequestMapping(value = "/api/user", method = RequestMethod.GET)
public String getAll() {
    System.out.println("查询所有用户信息...");
    return "ok";
}

RESTful - 新增

<!-- 保存用户 -->
<form th:action="@{/api/user}" method="post">
    <input type="submit" th:value="保存用户"/>
</form>
@RequestMapping(value = "/api/user", method = RequestMethod.POST)
public String save() {
    System.out.println("保存用户信息...");
    return "ok";
}

RESTful - 修改

RESTful规范中规定,如果要进行修改操作,需要发送PUT操作。

对于我们前端html中form表单如何发送一个PUT请求呢?

form表单要提交一个put请求处理步骤如下:

第一步:form表单必须是一个POST请求

第二步:在POST请求的表单中提交一个数据_method=PUT

第三步:在web.xml文件中配置一个SpringMVC的过滤器:HiddenHttpMethodFilter

<!-- 修改用户 -->
<form th:action="@{/api/user}" method="post">
    <!-- 隐藏域提交请求方式 -->
    <input type="hidden" name="_method" value="put">
    用户名:<input type="text" name="username">
    <input type="submit" value="修改用户"/>
</form>
<!-- 隐藏域HTTP请求方式过滤器 -->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    <!-- 修改隐藏域中参数名称,如果不配置则默认是_method -->
    <init-param>
        <param-name>methodParam</param-name>
        <param-value>realMethod</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
@RequestMapping(value = "/api/user", method = RequestMethod.PUT)
public String update(@RequestParam("username") String username){
    System.out.println("更新用户信息... + 用户名:" + username);
    return "ok";
}

关于HiddenHttpMethodFilter源码如下:

public class HiddenHttpMethodFilter extends OncePerRequestFilter {

    // 从这里可以看到做隐藏域的请求方式支持,PUT,DELETE,PATCH这三个请求方工
    private static final List<String> ALLOWED_METHODS =
          List.of(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name());

    // 从这里可以看出来隐藏域的name为"_method",这个也可以修改,在web.xml中添加<init-param>指定配置methodParam的值
    public static final String DEFAULT_METHOD_PARAM = "_method";
    private String methodParam = DEFAULT_METHOD_PARAM;


    public void setMethodParam(String methodParam) {
       Assert.hasText(methodParam, "'methodParam' must not be empty");
       this.methodParam = methodParam;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
          throws ServletException, IOException {

       HttpServletRequest requestToUse = request;
        // 先判断是否为post请求
       if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
           // 获取隐藏域中的参数值( 这里调用了请求的getParameter,所以要解决post中文乱码的Filter一定要出现在这个Filter的前面)
          String paramValue = request.getParameter(this.methodParam);
          if (StringUtils.hasLength(paramValue)) {
              // 如果隐藏域中指定参数存在值则把值转为大写(说明我们在写指定隐藏域中的值时大小写都可以)
             String method = paramValue.toUpperCase(Locale.ENGLISH);
             if (ALLOWED_METHODS.contains(method)) {
                 // 当提供的是值是put,delete,patch中任意一种则把请求方法转为其对应的
                requestToUse = new HttpMethodRequestWrapper(request, method);
             }
          }
       }

       filterChain.doFilter(requestToUse, response);
    }

    private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {

       private final String method;

       public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
          super(request);
          this.method = method;
       }

       @Override
       public String getMethod() {
          return this.method;
       }
    }

}

通过上面的原码可以看出来我们要表单提交put请求,时要求必须是一个post请求,在过滤器中进行的包装转为了对应的form表单中指定的请求类型。

二、RESTful CRUD实例

搭建基础环境

新建项目:usermgt

改POM

在pom文件中新增如下依赖

<dependencies>
    <!-- springmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>6.1.9</version>
    </dependency>
    <!-- logback -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.5.3</version>
    </dependency>
    <!-- servlet -->
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <version>6.0.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- thymeleaf和spring6整合 -->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring6</artifactId>
        <version>3.1.2.RELEASE</version>
    </dependency>
</dependencies>

注意:对于SpringMVC的使用我们要记得把pom.xml中的打包方式配置为war

添加web功能

1、项目中创建webapp目录

2、指定web根目录及创建web.xml

web.xml的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.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>forceRequestEncoding</param-name>
            <param-value>true</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>

    <!-- 隐藏域请求方式 -->
    <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>

    <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.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>

</web-app>

添加SpringMVC配置

<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 组件扫描 -->
    <context:component-scan base-package="com.xiaoxie"/>

    <!-- 前端控制器 -->
    <bean id=&
Spring MVC是一种基于MVC(Model-View-Controller)模式的Web框架,可以用于开发Web应用程序。下面是一个简单的Spring MVC登录注册示例。 1. 创建一个Maven项目,添加Spring MVC的依赖。 ```xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> ``` 2. 创建一个控制器(Controller)类,处理请求和响应。 ```java @Controller public class UserController { @RequestMapping("/login") public String login() { return "login"; } @RequestMapping("/register") public String register() { return "register"; } @RequestMapping("/doLogin") public String doLogin(@RequestParam String username, @RequestParam String password, Model model) { // 处理登录逻辑 if (isValid(username, password)) { model.addAttribute("username", username); return "welcome"; } else { model.addAttribute("error", "Invalid username or password"); return "login"; } } @RequestMapping("/doRegister") public String doRegister(@RequestParam String username, @RequestParam String password, Model model) { // 处理注册逻辑 if (isValid(username, password)) { model.addAttribute("username", username); return "welcome"; } else { model.addAttribute("error", "Invalid username or password"); return "register"; } } private boolean isValid(String username, String password) { // 验证用户名和密码是否正确 return true; } } ``` 3. 创建视图(View)文件,显示HTML页面。 - login.html ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> <h1>Login</h1> <form action="/doLogin" method="POST"> <div> <label for="username">Username:</label> <input type="text" id="username" name="username"> </div> <div> <label for="password">Password:</label> <input type="password" id="password" name="password"> </div> <button type="submit">Login</button> </form> <p style="color:red">${error}</p> </body> </html> ``` - register.html ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Register</title> </head> <body> <h1>Register</h1> <form action="/doRegister" method="POST"> <div> <label for="username">Username:</label> <input type="text" id="username" name="username"> </div> <div> <label for="password">Password:</label> <input type="password" id="password" name="password"> </div> <button type="submit">Register</button> </form> <p style="color:red">${error}</p> </body> </html> ``` - welcome.html ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Welcome</title> </head> <body> <h1>Welcome, ${username}!</h1> </body> </html> ``` 4. 配置Spring MVC,指定视图解析器(ViewResolver)和静态资源路径。 ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-5.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-5.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-5.2.xsd"> <context:component-scan base-package="com.example.controller" /> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".html" /> </bean> <mvc:resources mapping="/static/**" location="/static/" /> </beans> ``` 5. 运行Tomcat服务器,访问http://localhost:8080/login即可进入登录页面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值