java基础知识——SpringMVC(注解含义,过滤器,参数绑定,返回值处理,文件上传)

本文详细介绍了SpringMVC中的注解使用,包括@RequestMapping、@PathVariable、@RequestParam、@RequestHeader和@ModelAttribute。讨论了REST过滤器的原理,参数绑定的多种方式,如基本类型、JavaBean和集合类型,并提到了自定义转化器的实现。还阐述了返回值处理的方法,如返回String、void以及ModelAndView,以及如何处理文件上传。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注解含义

@RequestMapping

当它既出现在类上也出现在方法上时,类上注解值为请求URL的一级目录,方法上注解值为请求URL的二级目录
value:别名
method:指定HTTP请求方法(可选RequestMethod.GET,RequestMethod.HEAD,RequestMethod.POST,RequestMethod.PUT等)
params:指定请求参数的限制
@RequestMapping(params={“param1”}),表示请求参数中param1必须出现
@RequestMapping(params={"!param1"}),表示请求参数中param1不能出现
headers:限定HTTP请求中必须包含的请求头,同样支持简单的表达式

@PathVariable:出现在RequestMapping的value中,设置占位符

// 控制器类
@Controller
public class HelloController {
    @RequestMapping("/findAccount/{id}")
    public void findAccount(@PathVariable(name = "id") Integer accountId) {
        // accountId = 10
        // 方法体...
    }
}

访问URL:http://localhost:8080/findAccount/10会将10传给findAccount方法的accountId参数.

@RequestParam注解:

为处理器方法参数起别名

@RequestHeader

获取请求头参数

@ModelAttribute

若在方法上:优先于handler执行:
适用情况:若表单提交ID号,而handler想要数据库中的对应值,则可以在中间执行.
若在形参上:获取@ModelAttribute方法中返回的数据==如果没有,则会获取未经过@ModelAttribute处理的数据 ==
一个返回参数:利用返回值返回
多个返回参数:利用@ModelAttribute绑定handler中的形参

在这里插入图片描述
通过这个例子,我们可以推测,参数绑定也是利用Map的方式执行的

SessionAttribute

将本handler中的参数存入到Session中
默认配置视图解析器:

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

REST的过滤器

映射URL绑定的占位符
REST:资源表现层转化。即将资源显示呈现
1:delete对应删除,get对应查询,post对应修改,put对应增加
2:返回的是基本页面即404,500
但是页面的基本提交方式只有get和post,所以为了能够提交delete和put页面,需要实现过滤器
过滤器:
1:将HiddenHttpMethodFIlter配置到web.xml文件中。 能将特殊的post请求转化为delete和put请求
在这里插入图片描述
2:当想要发送delete请求时,只需要发送一个含有name="_method"value="DELETE"的post请求

< form action="springmvc/testRest/1" method="post">
< input type="hidden" name="_method" value="DELETE">
< /form>

此时这个请求就是一个DELETE请求
3:验证:RequestMapping的method="RequestMapping.DELETE"进行验证

参数绑定

数据绑定要求请求参数名和方法中的参数名相同,或使用@RequestParam为方法参数起别名.
三种类型:
基本数据类型和String类型
JavaBean类型
集合类型

基本类型

SpringMVC将请求参数中的param=value中的value传递给控制器方法的param参数,例如:

<a href="account/findAccount?accountId=10">查询账户</a>
// 控制器类
@Controller
@RequestMapping(path = "/account")
public class HelloController {
	@RequestMapping(path = "/findAccount")
	public void findAccount(Integer accountId) {
		// accountId = 10
		// 方法体...
	}
}

SpringMVC中会将10传给findAccount方法的accountID参数传递给HandlerAdapter执行

JavaBean类型的参数

级联映射
要想实现绑定,就必须实现其空参构造函数和所有属性的get,set方法
示例如下:

例如JavaBean类的定义如下:

public class Account implements Serializable {
    private String username;
    private Intger age;
    private User user;

	// 所有属性的getset方法...
}

public class User implements Serializable{
    private String uname;
    private Double umoney;
    // 所有属性的getset方法...
}

则其对应的请求参数名如下:

<form action="account/updateAccount" method="post">
    <label>名称</label><input type="text" name="username"><br/>
    <label>年龄</label><input type="text" name="age"><br/>
    <label>用户名</label><input type="text" name="user.uname"><br/>
    <label>用户余额</label><input type="text" name="user.umoney"><br/>
    <input type="submit" value="保存">
</form>
集合类型

对JavaBean类中的集合属性进行参数绑定,可以分为List类型的参数绑定和Set类型的参数绑定

对于List类型参数,其请求参数名为集合名[下标]

<input type="text" name="accounts[0].money"><br/>

对于Set类型参数,其请求参数名为集合名[键]

<input type="text" name="accountMap['one'].money"><br/>
自定义转化器

表单提交类型:字符串类型
方法参数:其他类型
所以赋值的时候需要转化,SpringMVC有携带默认的转换器Converter。当然我们也可以实现我们的自己的转换器Converter<String, T>。当需要String转换到T时,就会调用默认的转化器

// 自定义的类型转换器,完成从String类到Date类的转换

public class StringToDateConverter implements Converter<String, Date> {

    public Date convert(String source) {
        try {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            Date date = df.parse(source);
            return date;
        } catch (Exception e) {
            throw new RuntimeException("类型转换错误");
        }
    }
}

在Spring容器配置bean.xml中加入如下配置:

<!-- 配置的类型转换器工厂 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <!-- 诸如我们自定义的类型转换器 -->
            <bean class="cn.maoritian.utils.StringToDateConverter"/>
        </set>
    </property>
</bean>

注意:
当名字不同而想要绑定时:
@RequestParam注解: 为处理器方法参数起别名

<a href="testRequestParam?param1=value">测试requestParam注解</a>
处理器方法中给对应参数加上@RequestParam(name="param1")注解来接收参数

@RequestMapping("/testRequestParam")
public String handlerMethod(@RequestParam("param1") String username) {
    // 方法体...
}

返回值处理

返回:String对象
会根据String值返回到对应的JSP页面
return “success”;即返回到success.jsp

返回:void
当前URL对应的JSP页面
或者利用重定向或者转发
(1)request.getRequestDispatcher()是请求转发,前后页面共享一个request ; 这个是在服务端运行的,对浏览器来说是透明的。客户端发送一次请求,URL地址相同
return “forward”:/WEB_INF/pages/success.jsp"不会经过视图解析器
(2)response.sendRedirect()是重新定向,前后页面不是一个request。而这个是在浏览器端运行的。相当于客户端发送两次请求,URL地址不同
程序都会在执行完该句的情况下继续向下执行,因此在必要的时候应该使用return终止该方法。并且在之后操作request都没有意义,request.getRequestDispatcher执行时会生成一个新的request,而response会重新定向。
return “redirect:/success.jsp”; 会经过视图解析器

返回:ModelAndView
public ModelAndView addObject(Object attributeValue): 向当前页面的ModelMap对象中添加属性
public void setViewName(@Nullable String viewName): 指定返回视图

异步加载和响应JSON数据

默认条件下,前端控制器会拦截静态资源(css,js,jq)。所以需要配置web.xml禁止拦截

因此我们需要在Spring容器配置bean.xml中使用< mvc:resources>标签声明该资源为静态资源,否则请求该资源会报404错误.该标签的属性如下:
配置下列文件夹下的资源为静态资源

<!-- 配置静态文件的路径于对应的URL -->
<!-- location属性必须是一个有效的目录,因此必须以 / 结尾 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>

实现:
客户端页面:

<script>
// 页面加载,绑定单击事件
$(function () {
    $("#btn").click(function () {
        // 发送ajax请求
        $.ajax({
            // 配置请求参数
            url: "user/testAjax",
            contentType: "application/json;charset=UTF-8",
            dataType: "json",
            type: "post",
            // 请求的json数据
            data: '{"username":"myname","password":"mypassowrd","age":30}',
            // 回调函数,处理服务器返回的数据returnData
            success: function (returnData) {
                // 我们假定服务器返回的是一个user对象,将其输出在控制台上
                console.log(returnData);            }
        });
    });
});
</script>

handler:

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/testAjax")
    public @ResponseBody User testAjax(@RequestBody User user) {
    
        System.out.println(user);
        user.setUsername("myName")
        // 将user对象返回给前端页面
        return user;
    }
}

上述流程为:
1:客户端的data: '{“username”:“myname”,“password”:“mypassowrd”,“age”:30}'传入到服务器
2:handler中@RequestBody注解的对象接收数据,因为是一个user,@RequestBody将其封装
3:如果返回修改的user对象到,即return user。但是因为ajax页面接收的是json数据,所以需要@ResponseBody User,即在返回类型注解

文件上传

1:method为post
2:enctype为multipart/form-data
3:提供 type="file"的上传输入域
关于enctype的属性
一:application/x-www-form-urlencoded:
1:默认是application/x-www-form-urlencoded,键值对
2:如果action为get,则将表单数据编码为(name1=value1&name2=value2…),然后把这个字符串加到url后面,中间用?分隔
3:如果action为post,浏览器把form数据封装到http body中,然后发送到服务器。
二:text/plain:
表单以纯文本形式进行编码
三:multipart/form-data:
1:含有非文本内容,即含有文件(txt、MP3等)设置为multipart/form-data。
2:将表单中的数据变成二进制数据进行上传,所以这时候这时如果用request是无法直接获取到相应表单的值的

springmvc文件上传:
1:配置文件解析器,上传的请求先到达解析器,返回MultipartFile upload)

<!-- 配置文件解析器,其id是固定的,必须为multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置文件的最大尺寸 -->
    <property name="maxUploadSize" value="10485760"/>
</bean>

2:handler通过@RequestParam(“fileParam”) MultipartFile upload获取需要上传的文件对象,之后只需要为文件对象指定地址即可
@Controller
@RequestMapping("/fileUpload")
public class FileUploadController {

	@RequestMapping("/springMVC")
    public String fileupload2(HttpServletRequest request, @RequestParam("fileParam") MultipartFile upload) throws Exception {
        
        // 创建目录保存上传的文件
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }

        // 服务器中保存的文件名
        String filename = UUID.randomUUID().toString().replace("-", "") + "_" + upload.getOriginalFilename();
        // 上传文件
        upload.transferTo(new File(path,filename));

        return "success";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值