简单练习Spring MVC REST风格的代码

Spring MVC REST 项目分析

1. 项目结构整理

项目采用标准的Maven Web项目结构,主要包含以下内容:

text 复制代码
src/main/
├── java/com/zhang/       # Java源代码
│   ├── MyFilter.java      # 自定义过滤器(已注释)
│   ├── bean/              # 实体类
│   │   ├── Address.java   # 地址实体
│   │   └── User.java      # 用户实体
│   ├── controller/        # 控制器
│   │   ├── RequestController.java  # 请求处理控制器
│   │   ├── UserController.java     # REST风格用户控制器
│   │   └── UserController2.java    # 用户控制器(另一种实现)
│   └── dao/               # 数据访问层
│       └── UserDao.java   # 用户数据访问接口实现
├── resources/             # 资源文件
│   └── springmvc.xml      # Spring MVC配置文件
└── webapp/                # Web资源
    ├── WEB-INF/           # Web应用配置
    │   ├── lib/           # 库文件
    │   ├── page/          # 页面文件
    │   └── web.xml        # Web部署描述符
    ├── index.jsp          # 首页
    └── user.jsp           # 用户页面
pom.xml                    # Maven项目配置文件

2. 主要文件功能分析

配置文件

pom.xml

  • 定义项目基本信息(groupId、artifactId、version)
  • 设置打包方式为war
  • 引入Spring Web和Spring WebMVC依赖(5.2.3.RELEASE版本)
  • 配置Maven构建插件

springmvc.xml:

  • 配置组件扫描(com.zhang包)
  • 配置视图解析器(InternalResourceViewResolver),设置前缀和后缀

web.xml

  • 配置DispatcherServlet,指定Spring MVC配置文件位置
  • 配置编码过滤器(CharacterEncodingFilter)处理乱码问题
  • 配置请求方式转换过滤器(HiddenHttpMethodFilter)支持PUT/DELETE请求
  • 注释了自定义过滤器MyFilter

实体类

User.java

  • 用户实体类,包含id、name、age、gender属性
  • 关联Address对象
  • 提供构造函数、getter/setter方法和toString方法

Address.java

  • 地址实体类,包含province、city、town属性
  • 提供构造函数、getter/setter方法和toString方法

控制器

UserController.java

  • 实现RESTful风格的CRUD操作
  • 使用不同的HTTP请求方法区分操作类型:POST(新增)、GET(查询)、PUT(更新)、DELETE(删除)
  • 通过@RequestMapping注解指定请求路径和方法
  • 注入UserDao进行数据操作

UserController2.java

  • 展示表单数据自动绑定到User对象
  • 展示如何在控制器中使用原生Servlet API(HttpServletRequest、HttpServletResponse、HttpSession)
  • 包含乱码问题解决方案的注释说明

RequestController.java

  • 演示请求参数获取(@RequestParam注解)
  • 演示请求头信息获取(@RequestHeader注解)
  • 演示Cookie值获取(@CookieValue注解)
  • 详细说明了@RequestParam和@PathVariable的区别和使用场景

数据访问层

UserDao.java

  • 使用@Repository注解标识为数据访问组件
  • 实现基本的CRUD方法:save、update、delete、query
  • 目前为模拟实现,仅输出日志信息

3. 项目学习要点总结

通过这个项目,我们可以学习到以下Spring MVC相关知识:

  1. Spring MVC框架基础

    • 理解MVC架构模式在Web应用中的应用
    • 掌握Spring MVC的核心组件(DispatcherServlet、控制器、视图解析器等)
    • 学习Spring MVC的配置方式(XML配置)
  2. RESTful API设计与实现

    • 了解RESTful风格的API设计原则
    • 学习使用不同HTTP方法(GET、POST、PUT、DELETE)表示不同操作
    • 掌握通过@RequestMapping注解配置请求路径和方法
  3. 请求处理技术

    • 学习如何获取请求参数、请求头和Cookie信息
    • 掌握@RequestParam、@RequestHeader、@CookieValue等注解的使用
    • 了解表单数据自动绑定到JavaBean的原理
  4. 数据访问与模型层设计

    • 学习分层架构设计(控制器层、数据访问层)
    • 了解实体类的设计和关联关系
    • 掌握Spring的依赖注入(@Autowired注解)
  5. Web应用常见问题解决

    • 学习乱码问题的解决方案(编码过滤器)
    • 了解如何支持PUT/DELETE请求方法(HiddenHttpMethodFilter)
    • 掌握在Spring MVC中使用原生Servlet API
  6. 项目构建与部署

    • 学习使用Maven管理项目依赖和构建
    • 了解Web应用的打包方式(WAR)
    • 掌握Web应用的部署描述符配置(web.xml)

这个项目为初学者提供了Spring MVC框架的入门实践,涵盖了从基础配置到控制器实现、数据访问的完整流程,是学习RESTful Web服务开发的良好案例。

代码

bean
java 复制代码
public class Address {
    private String province;
    private String city;
    private String town;
}

public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;
    private Address address;
}
模拟dao
java 复制代码
import com.zhang.bean.User;
import org.springframework.stereotype.Repository;

import javax.servlet.http.HttpServletRequest;

@Repository
public class UserDao {
    public void save(User user) {
        System.out.println(this.getClass().getName() + "save");
        System.out.println("save();");
    }

    public void update(Integer id) {
        System.out.println("updete();");
        System.out.println(id);
    }

    public void delete(Integer id) {
        System.out.println("delete();");
        System.out.println(id);
    }

    public void query() {
        System.out.println("query();");
    }
}
过滤器
java 复制代码
package com.zhang;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(filterName = "MyFilter")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("init();");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println(this.getClass().getName() + "--------satrt");
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        chain.doFilter(req, resp);/*放行*/
        System.out.println(this.getClass().getName() + "--------stop");
    }


    @Override
    public void destroy() {
        System.out.println("destroy();");
    }


}
controller 层
java 复制代码
package com.zhang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class RequestController {

    /**
     * request.getParameter("name")
     *
     *
     * 当发送请求的时候,找到对应的处理方法之后,会根据参数的名称从request中获取对应的参数值,并封装到方法中
     * 此时要求,方法的名字和url中参数的名字必须一致,如果不一致,设置不成功
     *
     *
     * 如果设置的值不同,同时又想让参数获取到对应的属性值,可以通过@RequestParam来使用
     * 经常跟@PathVariable混淆,主要注意,两个注解有不同的用处
     *此注解的参数;
     * value:获取的参数值
     * required:表示当前属性值是否是必须存在的,默认值是true,表示请求中必须要包含此参数,如果没有,400,bad request
     *defaultValue:如果传递参数了,那么使用传递进来的参数,如果没有使用默认值
     *
     * 相信大家可能注意到了,@RequestParam和@PathVariable都能够完成类似的功能------因为本质上,它们都是用户的输入,只不过输入的部分不同,一个在URL路径部分,另一个在参数部分,简单的说就是url写法不同,如下:
     *
     * 使用@RequestParam时,URL是这样的:http://host:port/path?参数名=参数值
     *
     * 使用@PathVariable时,URL是这样的:http://host:port/path/参数值
     * @param name
     * @return
     */
    @RequestMapping("/testRequest")
    public String testRequest(@RequestParam(value = "username",required = false, defaultValue = "lisi")String name) {
        System.out.println(name);
        return "success";
    }
    /**
     *获取请求头信息
     * 通过@RequestHeader注解来表示
     * request. getHeader ( User-Agent)
     *
     * 同时也包含了几个参数
     * value:
     * required:
     * defaultValue :
     * 同@RequestParan
     */

    @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader("User-Agent") String userAgent) {
        System.out.println(userAgent);
        return "success";
    }

    /**
     * 获取cookie中的值,使用@Cookielalue注解
     *
     * 同时也包含了几个参数
     * value:
     * required:
     * defaultValue :
     * 同@RequestParan
     * Cookie[] cookies = request.getCookies();
     * @param jsid
     * @return
     */
    @RequestMapping("/testCookie")
    public String testCookie(@CookieValue("JSESSIONID") String jsid) {
        System.out.println(jsid);
        return "success";
    }
}

package com.zhang.controller;

import com.zhang.bean.User;
import com.zhang.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;

/**
 * localhost:8080/web_project/save
 * localhost:8080/web_project/update?id=1
 * localhost:8080/web_project/delete?id=1
 * localhost:8080/web_project/query
 *
 *我们在发送请求的时候有不同的请求方式,能不能通过请求方式来做一次转换
 *
 * PosT:    新增    /user
 * GET:     获取     / user
 * PUT:     更新      user/1
 * DELETE:  删除    /user/1
 *
 *
 */
@Controller
public class UserController {

    @Autowired
    private UserDao userDao;

    @RequestMapping(value = "/user" ,method = RequestMethod.POST)
//    @RequestMapping("/save")
    public String save(){
        System.out.println(this.getClass().getName()+"save");
        userDao.save(new User());
        return "success";
    }
    @RequestMapping(value = "/user" ,method = RequestMethod.PUT)
    public String update(Integer id){
        System.out.println(this.getClass().getName()+"update");
        userDao.update(id);
        return "success";
    }
    @RequestMapping(value = "/user" ,method = RequestMethod.DELETE)
    public String delete(Integer id){
        System.out.println(this.getClass().getName()+"delete");
        userDao.delete(id);
        return "success";
    }
    @RequestMapping(value = "/user" ,method = RequestMethod.GET)
    public String query(){
        System.out.println(this.getClass().getName()+"query");
        userDao.query();
        return "success";
    }
}

package com.zhang.controller;

import com.zhang.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

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

/**
 * 乱码问趣解决;
 * 我们需要设置request和response的编码方式,可以自己手动编写过滤器,也可以由现成的框架来实现
 * post:必须要分别设置request和response的编码格式
 * get:在tomcat的server.xml文件中,添加URIEncoding=utf-8
 *
 *在一个应用程序中可能会包含N多个过滤器, 这N多个过德器一般是没有顺序的要求的,
 * 但是如果你设置了编码过滤器,那么要求必须要将编码过滤器设置到最上面,保证编码过滤器优先执行
 */
@Controller
public class UserController2 {
    @RequestMapping("/testUser")
    public String testUser(User user){
        System.out.println(user);
        return "success";
    }

    /**
     * Controller中也支持原生Servlet的对象,需要在参数中给出
     *
     *
     * HttpServletRequest
     * HttpServletResponseHt tpSession
     * Locale:设置区域信息,国际化的操作
     * InputStream :
     * OutputStream
     * Reader:
     * Writer.
     *
     *
     * @param request
     * @param response
     * @param session
     * @return
     */
    @RequestMapping("/api")
    public String servletAPI(HttpServletRequest request, HttpServletResponse response, HttpSession session){
//        response.getWriter().write();
        request.setAttribute("request","request");
        session.setAttribute("session","session");
        return "success";
    }
}
前端
html 复制代码
<!-- index.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    pageContext.setAttribute("ctp",request.getContextPath());
//    加虚拟目录报错

%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/user" method="post">
    <input type="submit" value="新增">
</form>
<form action="/user" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="更新">
</form>
<form action="/user" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="删除">
</form>
<a href="/user" >查询</a>
</body>
</html>

<!-- user.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%pageContext.setAttribute("ctp", request.getContextPath());%>
<html>
<head>
    <title>User</title>
</head>
<body>
<%--<form action="${ctp}/testUser" method="post">--%>

<form action="/testUser" method="post">
    编号:<input type="text" name="id"><br>
    姓名:<input type="text" name="name"><br>
    年龄:<input type="text" name="age"><br>
    性别:<input type="text" name="gender"><br>
    省份:<input type="text" name="address.province"><br>
    城市:<input type="text" name="address.city"><br>
    区域:<input type="text" name="address.town"><br>
    <input type="submit" value="提交"><br>
</form>
</body>
</html>


<!-- WEN_INF/lib/success.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
操作成功<br>
request:${requestScope.get("request")}<br>
session:${sessionScope.get("session")}<br>
${requestScope.request}
<input value="${requestScope.get("request")}">
<input value="${requestScope.request}">
</body>
</html>
配置文件
web.xml
xml 复制代码
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<!--<?xml version="1.0" encoding="utf-8" ?>-->
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <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>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
<!--自定义过滤器-->
<!--  <filter>-->
<!--    <filter-name>myFilter</filter-name>-->
<!--    <filter-class>com.zhang.MyFilter</filter-class>-->
<!--  </filter>-->
<!--  <filter-mapping>-->
<!--    <filter-name>myFilter</filter-name>-->
<!--    <url-pattern>/*</url-pattern>-->
<!--  </filter-mapping>-->
  <!--springMVC提供的编码过滤器-->
  <filter>
    <filter-name>encoding</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>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
<!-- 此滤器完成请求方式的转换,将post请求转换为put或者delete-->
  <filter>
    <filter-name>hidden</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>hidden</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>
pom.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.zhang</groupId>
  <artifactId>springmvc_rest</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>springmvc_rest Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.3.RELEASE</version>
    </dependency>
  </dependencies>


  <build>
    <finalName>springmvc_rest</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
springmvc.xml
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="com.zhang"></context:component-scan>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

用到的jar

复制代码
jsp-api.jar
servlet-api.jar
相关推荐
尚学教辅学习资料4 天前
SSM从入门到实战:3.2 SpringMVC请求处理与控制器
spring·ssm·springmvc
郑州吴彦祖77214 天前
Spring MVC快速入门
spring·springmvc
Resean02231 个月前
SpringMVC 6+源码分析(二)DispatcherServlet实例化流程 1
java·spring boot·spring·servlet·springmvc
Resean02231 个月前
SpringMVC 6+源码分析(一)初始化流程
java·后端·spring·servlet·springmvc
惊涛骇浪、1 个月前
SpringMVC + Tomcat10
java·tomcat·springmvc
ruleslol2 个月前
springMVC04-Filter过滤器与拦截器
springmvc
ruleslol2 个月前
springMVC06-注解+配置类实现springMVC
springmvc
ruleslol2 个月前
springMVC01-特点、创建项目、@RequestMapping、获取参数请求,三种域对象
springmvc
ruleslol2 个月前
springMVC02-视图解析器、RESTful设计风格,静态资源访问配置
springmvc