【SpringMVC】请求——对应获得请求参数+相关问题的解决

二. 请求


1.1 请求参数的4种类型

客服端的请求参数的格式为:...?username=Alice&age=12...

SpringMVC框架接受到请求参数时,还可以对其进行封装:①基本类型 ②POJO类型 ③数组类型 ④集合类型

1.2 获得请求参数-基本类型

根据名称自动匹配。且可以自动类型转换(String -> ?)

@RequestMapping("/test1")
@ResponseBody
public void test10(String username, int age) throws IOException {
    
    
    System.out.println(username);
    System.out.println(age);
    // http://localhost:8080/test1?username=Alice&age=12
}

1.3 获得请求参数-POJO类型

竟然也可以根据名称自动匹配!

@RequestMapping("/test2")
@ResponseBody
public void test11(User user) throws IOException {
    
    
    System.out.println(user);
    // http://localhost:8080/test2?username=Alice&age=12
}

1.5 获得请求参数-数组类型

还是自动匹配。

@RequestMapping("/test3")
@ResponseBody
public void test3(String[] lolis) throws IOException {
    
    
    System.out.println(Arrays.toString(arr));
    // http://localhost:8080/test3?lolis=Alice&lolis=Cocoa&lolis=Hana
}

1.6 获得请求参数-集合类型

注意,这里不能直接根据请求参数名称自动匹配,而必须用POJO类型过渡一下。

重难点!!!弄清楚是如何过渡对应的!!!

domain.VO过渡类 ----------------------------------------------------------------------------

public class VO {
    
    

    private List<User> userList;

    // generate...
}
<!-- form.jsp页面 -- 简单的get方式不好模拟请求参数,因此使用表格post方式模拟请求参数 -->
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/test4" method="post">
        <input type="text" name="userList[0].username" />
        <input type="text" name="userList[0].age" />
        <br />
        <input type="text" name="userList[1].username" />
        <input type="text" name="userList[1].age" />
        <br />
        <input type="text" name="userList[2].username" />
        <input type="text" name="userList[2].age" />
        <br />
        <input type="submit" value="提交">
    </form>
</body>
</html>
@RequestMapping("/test4")
@ResponseBody
public void test4(VO vo) throws IOException {
    
    
    System.out.println(vo);
    // http://localhost:8080/form.jsp
}

1.7 获得请求参数-集合类型(特殊情况:Ajax的json请求参数)

当请求由Ajax发出,且contentType为json格式,则可用加上 @RequestBody 注解的集合类型直接获得。

<!-- ajax.jsp页面 -->
<html>
<head>
    <title>Title</title>
    <script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js" />
    <script>
        var userList = new Array();
        userList.push({
     
     username:"Alice",age:12});
        userList.push({
     
     username:"Hana",age:10});
        $.ajax({
     
     
            type:"POST",
            url:"${pageContext.request.contextPath}/test5",
            data:JSON.stringify(userList),
            contentType:"application/json;charset=utf-8"
        });
    </script>
</head>
<body>

</body>
</html>
@RequestMapping("/test5")
@ResponseBody
public void test5(@RequestBody List<User> userList) throws IOException {
    
    
    System.out.println(userList);
    // http://localhost:8080/ajax.jsp
}

 
 
 
 

2.1 找不到资源问题——静态资源访问权限的开启

当我们在SpringMVC框架下去访问诸如/js/jquery-3.3.1.js/img/pic1.jpg时,却显示找不到该目录或资源

这是因为,我们在配置整个框架的核心——前端控制器DispatcherServlet时,是这样写的:

<servlet>
     <servlet-name>DispatcherServlet</servlet-name>
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	 <!-- ... -->
</servlet>
<servlet-mapping>
     <servlet-name>DispatcherServlet</servlet-name>
     <url-pattern>/</url-pattern>
</servlet-mapping>

注意这句<url-pattern>/</url-pattern>,其含义是:所有的资源(动态资源/静态资源)都会被DispatcherServlet拦截。

所以,我们要做的,就是“放行”这些静态资源。换句话说,开放它们的访问权限。

在spring-mvc.xml中,有以下两种配置方式:

<!-- 1.开放静态资源的访问权限 -->
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/img/**" location="/img/" />

<!-- 2.访问静态资源的工作交给Tomcat -->
<mvc:default-servlet-handler />

 
 

2.2 中文数据乱码问题——全局utf-8过滤器

POST方式的中文请求数据,会出现乱码问题。我们使用一个全局过滤器进行解决。

<!-- 配置全局过滤器,解决中文乱码问题 -->
<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>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

 
 

2.5 参数名称不一致问题——绑定注解@RequestParam

请求的参数名称可能与接收的参数名称不一致。此时需要借助 @RequestParam 注解绑定这两个不同的名称。

@RequestMapping("/test6")
@ResponseBody
public void test6(@RequestParam("name") String username) throws IOException {
    
    
    System.out.println(username);
    // http://localhost:8080/test6?name=Alice
}

该注解非常强大:

-------------------------------------------------------------------------------------------
注解@RequestParam还可以配置的参数:
	- value: 请求参数的名称
	- required: 请求是否必须包含该参数(默认true)
	- defaultValue: 当请求不包含该参数时,则使用的默认值

-------------------------------------------------------------------------------------------

@RequestMapping("/test7")
    @ResponseBody
    public void test7(@RequestParam(value = "name", required = false, defaultValue = "Alice") String username) throws IOException {
    
    
        System.out.println(username);
        // http://localhost:8080/test7
    }

 
 

2.3 URL地址即参数问题——占位符注解@PathVariable

Restful风格的请求用“URL+请求方式(GET/POST/PUT/DELETE)”表示出一次目的。

并且,请求参数不再以?key=value的格式跟在URL尾巴后面,而是作为URL地址的一部分(比如http://localhost:8080/test/Alice)。

因此,在获取该请求参数时,需要借助占位符以及 @PathVariable 注解。

@RequestMapping("/test8/{username}")
@ResponseBody
public void test8(@PathVariable("username") String username) throws IOException {
    
    
    System.out.println(username);
    // http://localhost:8080/test8/Alice
}

 
 

2.4 日期格式问题——自定义类型转换工厂

SpringMVC时提供了默认的类型转换器,因此我们得以用int来接收String

但是日期的格式国家差异较大,SpringMVC可以将yyyy/MM/dd的字符串转换为日期类型,但对诸如yyyy-MM-dd的字符串便无能为力。

我们可以手写一个继承了Converter<S,T>接口的类型转换器,并将它加入到类型转换工厂中。

① 自定义类型转换器(converter.DateConverter.class)

public class DateConverter implements Converter<String, Date> {
    
    

    // 实现接口内部的convert方法
    public Date convert(String s) {
    
    
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
    
    
            date = format.parse(s);
        } catch (ParseException e) {
    
    
            e.printStackTrace();
        }
        return date;
    }
}

② 在配置文件中进行相关声明(spring-mvc.xml)

<!-- 将自定义的转换器加到转换器工厂当中 -->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="com.samarua.converter.DateConverter" />
        </list>
    </property>
</bean>

<!-- 在配置注解驱动时声明转换器工厂 -->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean" />

③ 测试

@RequestMapping("/test9")
@ResponseBody
public void test9(Date date) throws IOException {
    
    
    System.out.println(date);
    // http://localhost:8080/test9?data=2022-12-12
}

 
 

2.5 原生API问题——写在方法参数中自动注入

这个问题之前已经讲过:在SpringMVC框架环境下,想使用WebServlet原生API,可以将这些原生对象写在方法的参数中,调用者(即框架)会自动进行注入,我们放心使用即可。

@RequestMapping("/test10")
@ResponseBody
public void test10(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
    
    
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
}

 
 
 
 

3. 获取请求头

上面的所有内容,都是获取请求行的信息。下面,我们尝试获取请求头的信息。

首先明确,请求行的格式是【请求方式 请求url 请求协议/版本】,请求头的格式是【键值对】(看下图)

在这里插入图片描述

获取请求头中任意键值对的信息,使用 @RequestHeader 注解:

@RequestMapping("/test11")
@ResponseBody
public void test11(@RequestHeader(value = "User-Agent") String userAgent) throws IOException {
    
    
    System.out.println(userAgent);
}

特殊情况,直接获取请求头中Cookie中任意一个键值对的信息,使用 @CookieValue 注解:

@RequestMapping("/test12")
@ResponseBody
public void test12(@CookieValue(value = "JSESSIONID") String JSESSIONID) throws IOException {
    
    
    System.out.println(JSESSIONID);
}

 
 
 
 

 
 
 
 

 
 
 
 

More >_<

猜你喜欢

转载自blog.csdn.net/m0_46202073/article/details/114321204