Spring MVC - 请求处理

Spring MVC - 请求处理

1. 请求参数处理

1.1. @RequestParam
  • @RequestParam是Spring框架中的一个注解,用于将HTTP请求中的参数绑定到函数的参数上。当在控制器(Controller)的方法参数前使用此注解时,Spring会自动从HTTP请求的查询字符串中查找与注解中指定名称相匹配的参数,并将其值转换为方法参数的类型。
  • 其中一些常用的属性参数包括namedefaultValuerequired

下面是对这三个属性参数的详细解释:

  1. name属性:用于指定要提取的查询参数或表单参数的名称
  2. defaultValue属性:用于设置参数的默认值。(请求中没有提供相应的参数,将使用默认值)
  3. required属性:用于指定参数是否是必需的
    • 设置为 true,则请求中必须包含相应的参数
    • 设置为 false,则参数是可选的
/**
 * 控制器类,用于处理不同参数类型的请求。
 */
@Controller
public class ParamsController {
    /**
     * 处理路径为/testParams02的请求,通过请求参数获取名称。
     *
     * @param name 请求参数中的用户名。
     * @return 指向/index.jsp的字符串,用于展示请求结果。
     */
    @RequestMapping("/testParams02")
    public String testParams02(@RequestParam(value = "username") String name) {
        System.out.println("name:" + name);
        return "/index.jsp";
    }

    /**
     * 处理路径为/testParams03的请求,通过可选的请求参数获取名称。
     *
     * @param name 请求参数中的用户名,允许为空。
     * @return 指向/index.jsp的字符串,用于展示请求结果。
     */
    @RequestMapping("/testParams03")
    public String testParams03(@RequestParam(value = "username", required = false) String name) {
        System.out.println("name:" + name);
        return "/index.jsp";
    }

    /**
     * 处理路径为/testParams04的请求,通过请求参数获取名称,如果参数未提供,则使用默认值。
     *
     * @param name 请求参数中的用户名,如果未提供,则默认为"张三"。
     * @return 指向/index.jsp的字符串,用于展示请求结果。
     */
    @RequestMapping("/testParams04")
    public String testParams04(@RequestParam(value = "username", defaultValue = "张三") String name) {
        System.out.println("name:" + name);
        return "/index.jsp";
    }

    /**
     * 处理路径为/testParams05的请求,通过模型属性获取用户实体。
     *
     * @param userEntity 包含用户信息的实体对象。
     * @return 指向/index.jsp的字符串,用于展示请求结果。
     */
    @RequestMapping("/testParams05")
    public String testParams05(UserEntity userEntity) {
        System.out.println("userEntity:" + userEntity);
        return "/index.jsp";
    }
}
1.2. @RequestHeader
  • @RequestHeaderSpring框架中的一个注解,用于将HTTP请求头中的信息绑定到控制器方法的参数上。当在控制器方法的参数前使用此注解时,Spring会自动从HTTP请求头中查找与注解中指定名称相匹配的头信息,并将其值转换为方法参数的类型。
/**
 * 控制器类,用于处理与请求头相关的请求。
 */
@Controller
public class HeadersController {

    /**
     * 处理/testHeader01路径的请求,演示如何获取特定请求头的值。
     *
     * @param accept 通过请求头Accept获取的值,用于客户端表明它能接受的媒体类型。
     * @return 返回/index.jsp,指示视图解析器将请求重定向到index.jsp页面。
     */
    @RequestMapping("/testHeader01")
    public String testHeaders01(@RequestHeader("Accept") String accept) {
        System.out.println("accept: " + accept);
        return "/index.jsp";
    }

    /**
     * 处理/testHeader02路径的请求,演示如何获取所有请求头的值。
     *
     * @param headers 通过@RequestHeader注解以Map形式接收所有请求头,键为请求头名称,值为请求头的值。
     * @return 返回/index.jsp,指示视图解析器将请求重定向到index.jsp页面。
     */
    @RequestMapping("/testHeader02")
    public String testHeaders02(@RequestHeader Map<String, String> headers) {
        System.out.println(headers);
        return "/index.jsp";
    }
}
1.3. @CookieValue
  • @CookieValueSpring框架中的一个注解,用于将HTTP请求中的Cookie信息绑定到控制器方法的参数上。当在控制器方法的参数前使用此注解时,Spring会自动从HTTP请求的Cookie中查找与注解中指定名称相匹配的Cookie,并将其值转换为方法参数的类型。
/**
 * 控制器类,用于处理与Cookie相关的请求。
 */
@Controller
public class CookieController {

    /**
     * 处理测试Cookie的请求。
     * 该方法旨在演示如何从Cookie中获取值,并且如何返回一个视图名称。
     *
     * @param cookie 从Cookie中获取的JSESSIONID值,用于识别会话。
     * @return 返回视图名称"/index.jsp",用于指示浏览器加载对应的JSP页面。
     */
    @RequestMapping("/testCookie")
    public String testCookie(@CookieValue("JSESSIONID") String cookie) {
        System.out.println(cookie);
        return "/index.jsp";
    }
}
1.4. 乱码问题的解决
  • 对于 GET 请求乱码问题,可以通过配置 SpringMVCCharacterEncodingFilter 过滤器来解决。
1.4.1. web.xml 版
  • src/main/webapp/WEB-INF/web.xml
    <!-- 配置字符编码过滤器,确保请求和响应的字符编码为UTF-8 -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!-- 设置字符编码为UTF-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <!-- 强制对请求和响应进行UTF-8编码 -->
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <!-- 将字符编码过滤器应用于名为springmvc的Servlet -->
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <servlet-name>springmvc</servlet-name>
    </filter-mapping>
1.4.2. Config 版
  • src/main/java/com/springmvc/config/MyWebAppInitializer.java
    /**
     * 配置应用于所有Servlet的过滤器。
     * 返回一个过滤器数组,这里定义了一个字符编码过滤器,用于确保所有请求和响应都使用UTF-8编码。
     * 通过强制设置编码,可以避免由于编码不一致导致的问题。
     *
     * @return 过滤器数组
     */
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        // 设置字符编码为UTF-8
        characterEncodingFilter.setEncoding("UTF-8");
        // 强制设置编码,确保所有请求和响应都使用UTF-8编码。
        characterEncodingFilter.setForceEncoding(true);
        return new Filter[]{characterEncodingFilter};
    }

2. 请求映射处理

2.1. @RequestMapping

@RequestMapping注解是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上(以该地址作为父路径)。

  • params : 设置请求必须的请求参数
    1. 必须存在某参数 params = {"username"}
    2. 必须不存在某参数 params = {"!username"}
    3. 参数必须等于什么值 params = {"username=张三"}
    4. 参数必须不等于什么值 params = {"!username=张三"}
  • headers : 设置请求必须的请求头
    • headers = {"Accept"}
  • consums : 设置请求必须的请求内容类型
    • consumes = {"application/json"}
  • produces : 设置响应内容的类型
    • produces = {"application/json"}
  • 映射路径的通配符
    1. ? 匹配一个字符
    2. *匹配0个或多个字符
    3. ** 匹配0个或多个路径部分
/**
 * 控制器类,负责处理与特定URL路径匹配的HTTP请求。
 */
@Controller
@RequestMapping("/mapping")
public class MappingController {

    /**
     * 处理/testMapping01路径的GET请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping("/testMapping01")
    public String testMapping01() {
        System.out.println("映射成功!");
        return "/index.jsp";
    }

    /**
     * 处理/testMapping02路径的GET和POST请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping02", method = {RequestMethod.GET, RequestMethod.POST})
    public String testMapping02() {
        System.out.println("映射成功!");
        return "/index.jsp";
    }

    /**
     * 当请求参数中包含username时处理/testMapping03路径的请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping03", params = {"username"})
    public String testMapping03() {
        System.out.println("映射成功!");
        return "/index.jsp";
    }

    /**
     * 当请求参数中不包含username时处理/testMapping04路径的请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping04", params = {"!username"})
    public String testMapping04() {
        System.out.println("映射成功!");
        return "/index.jsp";
    }

    /**
     * 当请求参数username的值为张三时处理/testMapping05路径的请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping05", params = {"username=张三"})
    public String testMapping05() {
        System.out.println("映射成功!");
        return "/index.jsp";
    }

    /**
     * 当请求参数username的值不为张三时处理/testMapping06路径的请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping06", params = {"username!=张三"})
    public String testMapping06() {
        System.out.println("映射成功!");
        return "/index.jsp";
    }

    /**
     * 当请求头中包含Accept字段时处理/testMapping07路径的请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping07", headers = {"Accept"})
    public String testMapping07() {
        System.out.println("映射成功:headers");
        return "/index.jsp";
    }

    /**
     * 当请求内容类型为application/json时处理/testMapping08路径的请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping08", consumes = {"application/json"})
    public String testMapping08() {
        System.out.println("映射成功:consumes");
        return "/index.jsp";
    }

    /**
     * 当响应内容类型为application/json时处理/testMapping09路径的请求。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/testMapping09", produces = {"application/json"})
    public String testMapping09() {
        System.out.println("映射成功:produces");
        return "/index.jsp";
    }

    /**
     * 处理/testMapping10路径的GET请求,展示通配符?的使用。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/ant?")
    public String testMapping10() {
        System.out.println("通配符 ==> ?");
        return "/index.jsp";
    }

    /**
     * 处理/testMapping11路径的GET请求,展示通配符*的使用。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "/ant*")
    public String testMapping11() {
        System.out.println("通配符 ==> *");
        return "/index.jsp";
    }

    /**
     * 处理任意路径下/ant/**结构的请求,展示通配符**的使用。
     *
     * @return 指向/index.jsp的字符串,用于显示一个简单的欢迎页面。
     */
    @RequestMapping(value = "**/ant/**")
    public String testMapping12() {
        System.out.println("通配符 ==> **");
        return "/index.jsp";
    }
}
2.2. @PathVariable
  • @PathVariableSpring框架中的一个注解,用于在控制器方法的参数中注入从URL路径中提取的变量值。当URL中的某个部分被定义为变量时(通常使用大括号{}包裹),该注解可以用来将这部分变量映射到控制器方法的参数上。
/**
 * 控制器类,处理与路径相关的请求。
 */
@Controller
public class PathController {

    /**
     * 处理用户ID路径变量的请求。
     *
     * @param id 用户的ID,由路径变量提供。
     * @return 指向index.jsp的字符串路径。
     * URL:http://localhost:8080/user/1
     */
    @RequestMapping("/user/{id}")
    public String testPathVariable01(@PathVariable("id") Integer id) {
        System.out.println("id = " + id);
        return "/index.jsp";
    }

    /**
     * 处理用户名和用户ID路径变量的请求。
     *
     * @param username 用户的用户名,由路径变量提供。
     * @param id       用户的ID,由路径变量提供。
     * @return 指向index.jsp的字符串路径。
     * URL:http://localhost:8080/user/张三/1
     */
    @RequestMapping("/user/{username}/{id}")
    public String testPathVariable02(@PathVariable("username") String username, @PathVariable("id") Integer id) {
        System.out.println("username = " + username);
        System.out.println("id = " + id);
        return "/index.jsp";
    }
}
2.3. REST

REST(Representational State Transfer,表述性状态转移)是一种软件架构风格,主要用于设计网络应用程序的结构。REST架构风格是由Roy Fielding博士在其2000年的博士论文中提出的,他是HTTP协议的主要设计者之一。REST风格强调了几个核心概念,包括:

  1. 无状态(Stateless):服务器端的响应不应依赖于客户端保存的状态信息,每次请求都应包含处理该请求所需的所有信息。

  2. 客户端-服务器(Client-Server):架构将功能分为客户端和服务端两部分,客户端负责用户交互和展示,服务器负责存储和处理数据。

  3. 缓存(Cacheable):响应可以标记为可缓存或不可缓存,这可以提高效率和性能。

  4. 统一接口(Uniform Interface):这是REST架构中最显著的特点,它简化了客户端与服务端的交互,主要通过以下几点体现:

    • 资源的识别通过URI(统一资源标识符);

    • 对资源的操作通过标准的方法,如GET、POST、PUT、DELETE等HTTP方法;

    • 资源表示的可变性,即资源可以通过不同的格式(如HTML、JSON、XML)来表示;

    • 超媒体作为应用状态引擎(HATEOAS),即响应中包含链接到其他相关资源的信息,使得客户端能够发现和访问更多资源。

  5. 分层系统(Layered System):允许中间组件加入而不影响客户端或服务器,比如代理服务器和网关。

  6. 按需代码(Code on Demand):虽然这不是强制性的,但它允许服务器临时扩展客户端的功能,例如通过JavaScript脚本。

RESTful服务通常使用HTTP协议,因为它天然支持REST的核心原则。例如,GET方法用于检索资源,POST用于创建新资源,PUT用于更新现有资源,DELETE用于删除资源。RESTful API设计应该遵循这些原则,以便于理解和使用,同时保持良好的可扩展性和互操作性。

/**
 * 控制器类,用于处理RESTful API请求。
 */
@Controller
public class RestController {

    /**
     * 处理GET请求,通过路径参数获取特定ID的信息。
     *
     * @param id 用户ID,作为路径参数传递。
     * @return 返回指向index.jsp的路径,用于展示查询结果。
     */
    @GetMapping("/testRest/{id}")
    public String query(@PathVariable("id") Integer id) {
        System.out.println("已查询:" + id);
        System.out.println("@GetMapping");
        return "/index.jsp";
    }

    /**
     * 处理PUT请求,用于更新用户信息。
     *
     * @param userEntity 包含更新后用户信息的实体对象。
     * @return 返回指向index.jsp的路径,用于展示更新结果。
     */
    @PutMapping("/testRest")
    public String update(UserEntity userEntity) {
        System.out.println("已修改:" + userEntity);
        System.out.println("@PutMapping");
        return "/index.jsp";
    }

    /**
     * 处理POST请求,用于添加新用户信息。
     *
     * @param userEntity 包含新用户信息的实体对象。
     * @return 返回指向index.jsp的路径,用于展示添加结果。
     */
    @PostMapping("/testRest")
    public String create(UserEntity userEntity) {
        System.out.println("已添加:" + userEntity);
        System.out.println("@PostMapping");
        return "/index.jsp";
    }

    /**
     * 处理DELETE请求,通过路径参数删除特定ID的用户信息。
     *
     * @param id 用户ID,作为路径参数传递,用于指定要删除的用户。
     * @return 返回指向index.jsp的路径,用于展示删除结果。
     */
    @DeleteMapping("/testRest/{id}")
    public String delete(@PathVariable("id") Integer id) {
        System.out.println("已删除:" + id);
        System.out.println("@DeleteMapping");
        return "/index.jsp";
    }
}
2.4. 静态资源访问
2.4.1. xml 版
  • src/main/resources/spring-web-config.xml
<!-- 启用基于注解的控制器,使得Spring MVC可以自动识别和处理使用了注解的控制器类 -->
<mvc:annotation-driven/>

<!-- 配置1 -->
<!-- 配置静态资源的处理,指定任何以/images/开头的URL请求都映射到/images/目录下对应的静态资源 -->
<mvc:resources mapping="/images/**" location="/images/" />

<!-- 配置2 -->
<!-- 添加默认的Servlet处理程序,用于处理Spring MVC未显式映射的其他所有请求 -->
<mvc:default-servlet-handler/>

  • 配置二选一即可,建议配置 1
2.4.2. Config 版
  • src/main/java/com/springmvc/config/SpringWebConfig.java
/**
 * Spring MVC的配置类,用于配置Spring Web的相关特性。
 */
@Configuration
@ComponentScan(basePackages = {"com.springmvc.controller"})
public class SpringWebConfig implements WebMvcConfigurer {
    
    /**
     * 配置静态资源的处理方式。
     * 该方法用于告诉Spring MVC如何处理应用中的静态资源,如图片。
     * @param registry ResourceHandlerRegistry实例,用于注册和配置资源处理器。
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 配置对/images/路径下资源的处理,资源位于classpath:/images/目录下
        registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/");
    }
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`feign-spring-mvc-starter` 是一个 Feign 的扩展,它支持使用 Spring MVC 注解来定义和调用 REST 服务。使用 `feign-spring-mvc-starter`,你可以像使用 Spring MVC 控制器一样定义 Feign 客户端,从而更方便地进行 REST 服务的开发。 在使用 `feign-spring-mvc-starter` 之前,你需要先了解 Feign 和 Spring MVC 的基本概念和用法。 Feign 是一个声明式的 Web 服务客户端,它可以帮助你更方便地定义和调用 REST 服务。Feign 的基本使用方法是定义一个接口,用于描述 REST 服务的 API,然后使用 Feign 注解来声明这个接口。 Spring MVC 是一个基于 Java 的 Web 框架,它提供了一组注解和 API,用于处理 Web 请求和响应。 `feign-spring-mvc-starter` 将 Feign 和 Spring MVC 结合起来,使你可以使用 Spring MVC 注解来定义和调用 REST 服务。使用 `feign-spring-mvc-starter`,你可以更方便地使用 Feign 来调用 REST 服务。 以下是一个使用 `feign-spring-mvc-starter` 的示例: 1. 添加 Maven 依赖 在 pom.xml 文件中添加以下依赖项: ```xml <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-spring-mvc</artifactId> <version>5.3.1</version> </dependency> ``` 2. 定义 Feign 接口 定义一个 Feign 接口,用于描述 REST 服务的 API。例如: ```java @FeignClient(name = "example-service") public interface ExampleClient { @GetMapping("/example") String getExample(); } ``` 在这个接口中,我们使用了 `@FeignClient` 注解来声明这个接口是一个 Feign 客户端,并指定了服务的名称。然后,我们定义了一个 `getExample()` 方法,用于调用 example-service 服务的 /example 路径。 3. 定义 Spring MVC 控制器 定义一个 Spring MVC 控制器,用于处理来自客户端的请求。例如: ```java @RestController public class ExampleController { private final ExampleClient exampleClient; public ExampleController(ExampleClient exampleClient) { this.exampleClient = exampleClient; } @GetMapping("/") public String index() { return exampleClient.getExample(); } } ``` 在这个控制器中,我们注入了 `ExampleClient`,并在 `index()` 方法中使用它来调用 example-service 服务的 /example 路径。 4. 运行应用程序 现在,你可以运行应用程序并访问 http://localhost:8080/ ,你应该会看到来自 example-service 服务的响应。 这就是一个使用 `feign-spring-mvc-starter` 的示例。使用 `feign-spring-mvc-starter`,你可以更方便地使用 Feign 来调用 REST 服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值