SpringMVC_数据返回/文件上传
返回数据
在controller中根据返回值类型,大致可以分为String,void,ModelAndView。
1. 当返回类型为String类型: 返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址;
代码示例:
<!--jsp代码-->
<a href="user/testString">返回类型String</a>
<!--控制器代码-->
@RequestMapping("/testString")
public String testString(Model model){
//模拟从数据库中查询对象
User user = new User();
user.setUsername("美美");
user.setPassword("123");
user.setAge(20);
model.addAttribute("user",user);
return "success";
}
<!--success.jsp,jsp代码-->
${user}
访问地址及视图效果:
2. 当返回类型是void类型: 执行程序报404的异常,默认查找JSP页面没有找到;可以使用请求转发或者重定向跳转到指定的页面;
代码示例:
<!--jsp代码-->
<a href="user/testVoid">返回类型Void</a>
<!--控制器代码-->
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
//第一种:请求转发
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
//第二种:重定向
response.sendRedirect(request.getContextPath()+"/index.jsp");
//第三种:直接会进行响应,先设置中文乱码
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("你好");
return;
}
访问地址及视图效果:
请求转发
重定向
直接访问
注意点:
WEB-INF: WEB-INF目录下面的内容对客户端是不可见的,所以只能由服务器级别才能访问,客户端不能访问。
Forword: 转发是一次请求,是服务器级别,浏览器的地址不会变。因为客户端发送一个请求,服务器受理之后,发现要请求内容还要再去别的请求,那么转发就是服务器自己去处理完成。不麻烦客户端(浏览器)了,所以客户端上面的地址栏不会改变。
Redirect: 重定向是二次请求,是客户端级别的。服务器收到请求后,发现还要去请求别的内容,但是服务器自己不想处理,那么就告诉客户端自己去处理,那么客户端就去请求那个别的内容了。所以客户端(浏览器)地址栏就会改变了。
3. 当返回类型是ModelAndView类型: ModelAndView对象是Spring提供的一个对象,该对象也可以用作控制器方法的返回值,用来调整具体的JSP视图;
代码示例:
<!--jsp代码-->
<a href="user/testModelAndView">返回类型ModelAndView</a>
<!--控制器代码-->
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
// 第一步:创建ModelAndView对象
ModelAndView mv = new ModelAndView();
// 模拟从数据库中查询出User对象
User user = new User();
user.setUsername("哈哈");
user.setPassword("456");
user.setAge(30);
// 第二步:把user对象存储到mv对象中,把user对象存入到request对象
mv.addObject("user",user);
// 第三步:跳转页面
mv.setViewName("success");
return mv;
}
访问地址及视图效果:
注意点
项目开始之前,在web.xml中配置了核心控制器,DispatcherServlet会拦截到所有的资源,导致问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。在springmvc.xml配置文件添加如下配置:
<!--前端控制器,配置静态资源不拦截-->
<!--location:表示webapp目录下的包下的所有文件;-->
<!--mapping:表示以/static开头的所有请求路径;-->
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
文件上传
文件上传的必要前提
1,form 表单的 enctype 取值必须是,multipart/form-data,(默认值是:application/x-www-form- urlencoded,当 form 表单的 enctype 取值不是默认值后, request.getParameter()将失效);
2,method 属性取值必须是 Post,因为get有长度限制;
3,提供<input type=”file” />标签进行文件选择上传;
代码示例:
<form action="/user/testFileupload" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload" /><br/>
<input type="submit" value="上传" />
</form>
JavaEE文件上传
JavaEE文件上传思路就是通过对request对象进行解析,然后遍历表单中文件项进行文件上传;
代码示例:
/**
* 文件上传
* @return
*/
@RequestMapping("/testFileupload")
public String testFileupload(HttpServletRequest request) throws Exception {
// 使用fileupload组件完成文件上传
// 上传路径
String path = request.getSession().getServletContext().getRealPath("/uploads/");
// 判断,该路径是否存在
File file = new File(path);
if(!file.exists()){
// 创建该文件夹
file.mkdirs();
}
// 解析request对象,获取上传文件项
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析request
List<FileItem> items = upload.parseRequest(request);
// 遍历
for(FileItem item:items){
// 进行判断,当前item对象是否是上传文件项
if(item.isFormField()){
// 说明普通表单向
}else{
// 说明上传文件项
// 获取上传文件的名称
String filename = item.getName();
// 完成文件上传
item.write(new File(path,filename));
// 删除临时文件
item.delete();
}
}
return "success";
}
SpringMVC文件上传原理
图片来源于黑马视频
SpringMVC单服务器文件上传
SpringMVC提供了文件解析器实现文件上传,通过getOriginalFilename()方法获取上传文件的名称,通过transferTo()方法进行文件上传;
文件解析器配置:
<!--配置文件解析器对象-->
<!-- id的值是固定的-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760" />
</bean>
代码示例:
/**
* SpringMVC文件上传
* @return
*/
@RequestMapping("/testfileupload")
//MultipartFile对象的参数名要与jsp页面的表单文件项name一样
public String testfileuoload(HttpServletRequest request, MultipartFile upload) throws Exception {
// 使用fileupload组件完成文件上传
// 上传路径
String path = request.getSession().getServletContext().getRealPath("/uploads/");
// 判断,该路径是否存在
File file = new File(path);
if(!file.exists()){
// 创建该文件夹
file.mkdirs();
}
// 说明上传文件项
// 获取上传文件的名称
String filename = upload.getOriginalFilename();
// 完成文件上传
upload.transferTo(new File(path,filename));
return "success";
}
SpringMVC跨服务器文件上传
SpringMVC提供jersey组件进行跨服务器文件上传
代码示例:
/**
* 跨服务器文件上传
* @return
*/
@RequestMapping("/testfileupload")
public String testfileuoload(MultipartFile upload) throws Exception {
// 定义上传文件服务器路径
String path = "http://localhost:9090/uploads/";
// 说明上传文件项
// 获取上传文件的名称
String filename = upload.getOriginalFilename();
// 创建客户端的对象
Client client = Client.create();
// 和图片服务器进行连接
WebResource webResource = client.resource(path + filename);
// 上传文件
webResource.put(upload.getBytes());
return "success";
}
注意点:
如果进行跨服务器文件上传中报错,在文件服务器Tomcat配置中加入以下代码,表示接收文件的目标服务器可以支持写入操作 。
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>