一、响应数据和结果视图
1. 返回值分类之:字符串
controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。
2. 返回值分类之:void
Servlet原始Api可作为控制器中方法的参数,在Controller方法形参上定义request和response,使用request和response指定响应结果。
3. 返回值分类之:ModelAndView对象
ModelAndView是spring提供的一个对象,可以用来调整具体的JSP视图。
二、响应之转发和重定向
- forward转发:
Controller方法在提供了String类型的返回值之后,默认就是请求转发。
需要注意的是:如果用了formward,则路径必须写成实际视图url,不能写逻辑视图。
使用请求转发,既可以转发到jsp,也可以转发到其他的控制器方法。//相当于 request.getRequestDispatcher("url").forward(request,response)
-
redirect重定向
三、ResponseBody响应json数据
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img,css,js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截。
在SpringMvc.xml配置文件中添加如下配置:
<!--前端控制器,配置那些资源不用拦截 -->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
-
使用@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.0</version>
</dependency>
二、SpringMVC实现文件上传
1. 文件上传的必要前提
- form表单的enctype取值必须是:multipart/form-data(默认值是:application/x-www-from-urlencoded)
enctype:是表单请求正文的类型。 - method属性取值必须是post
- 提供一个文件选择域
<input type = "file" />
2.文件上传的原理属性:
- 当form表单的enctype取值不是默认后,request.getParameter()将失效。enctype="application/x-www-form-urlencoded"时,form表单的正文内容是:key=value&key=value&key=value
- 当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就会变成:
每一部分都是MIME类型描述的正文。 -
借助第三方组件实现文件上传:
使用Commons-fileUpload组件实现文件上传,需要导入该组件相应的jar包:Commons-fileupload和Commons-io。commons-io不属于文件上传组件开发的jar文件,但Commons-fileUpload组件从1.1版本开始,它工作时需要commons-io包的支持。
3. jsp文件上传表单的实现
<h3>文件上传</h3>
<form action="file/upload" method="post" enctype="multipart/form-data">
选择上传文件:<input type="file" name="upload"/><br/>
<input type="submit" value="上传"/>
</form>
4. SpringMVC中文件解析器的配置
<!--配置文件解析器
文件上传的id是固定的,不能起别的名称,否则无法实现请求参数的绑定。
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
5. 文件上传代码实现
package com.seapp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.RequestPartServletServerHttpRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* @author seapp
* @date 2020/8/3 23:14
*/
@Controller
@RequestMapping("/file")
public class FileUploadController {
/**
* 实现文件上传
*
* @return
*/
@RequestMapping("/upload")
public String fileUpload(HttpServletRequest request, MultipartFile upload) throws IOException {
System.out.println("SpringMVC文件上传开始");
//获取文件上传路径
String path = request.getSession().getServletContext().getRealPath("/uploads/");
//判断该文件是否存在,不存在则创建该文件
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
//获取上传文件信息
String filename = upload.getOriginalFilename();
//把文件的名称设置唯一值,uuid
filename = UUID.randomUUID().toString().replace("-", "") + "_" + filename;
//完成文件上传
upload.transferTo(new File(path,filename));
return "success";
}
}
6.SpirngMVC跨服务器方式实现文件上传
- 三方访问依赖的引入:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
- 文件跨服务传输的具体实现:
/**
* 实现文件上传
*
* @return
*/
@RequestMapping("/upload")
public String fileUpload(HttpServletRequest request, MultipartFile upload) throws IOException {
System.out.println("SpringMVC文件上传开始");
String path = "http://localhost:8090/uplods/";
//获取上传文件信息
String filename = upload.getOriginalFilename();
//把文件的名称设置唯一值,uuid
filename = UUID.randomUUID().toString().replace("-", "") + "_" + filename;
//创建客户端对象
Client client = Client.create();
WebResource webResource = client.resource(path + filename);
//完成文件上传
webResource.put(upload.getBytes());
return "success";
}
三、SpringMVC中的异常处理
1. 自定义异常类(做提示信息的)
package com.seapp.exception;
/**
- 自定义异常处理类
- @author seapp
- @date 2020/8/4 15:53
*/
public class SysException extends Exception {
private String message;
public SysException(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
2. 编写异常处理器
package com.seapp.exception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 异常处理器
* @author seapp
* @date 2020/8/4 15:57
*/
public class SysExceptionResolver implements HandlerExceptionResolver {
/**
* 异常处理逻辑
* @param request
* @param response
* @param handler
* @param ex
* @return
*/
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
//获取异常对象
SysException e = null;
if(ex instanceof SysException){
e = (SysException) ex;
}else {
e = new SysException("系统正在维护...");
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("errorMsg",e.getMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
3. 配置异常处理器(跳转到友好处理界面 )
<!--配置异常处理器 -->
<bean id="sysExceptionResolver" class="com.seapp.exception.SysExceptionResolver"/>
四、SpringMVC中的拦截器
1. 拦截器
- Spring MVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
- 用户可以自己定义一些拦截器来实现特定功能。
- 谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
- 过滤器与拦截器的区别:
①:过滤器是Servlet规范中的一部分,任何Java web工程都可以使用。
②:拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能用。
③:过滤器在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截。
④:拦截器它是只会拦截访问的控制器方法,如果访问的是jsp、html、css、image或者js是不会进行拦截的。 - 它也是AOP思想的具体应用。
- 我们要想自定义拦截器,要求必须实现"HandlerInterceptor"接口。
2.拦截器实现
- 编写拦截器,实现HandlerInterceptor接口
package com.seapp.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义拦截器
* @author seapp
* @date 2020/8/4 16:47
*/
public class MyInterceptor implements HandlerInterceptor {
/**
* 拦截器预处理
* @param request
* @param response
* @param handler
* @return
* true:放行,若拦截链中还有拦截器,则执行下个拦截器。若没有,则执行Controller中的方法
* false:拦截。使用request/response参数,直接跳转至指定界面。
*
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
return true;
}
/**
* 后处理的方法
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 最后执行的方法
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
}
}
- 配置拦截器(springmvc.xml)
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--要拦截的方法-->
<mvc:mapping path="/user/**"/>
<!--不要拦截的方法-->
<!-- <mvc:exclude-mapping path="/**"/>-->
<!--配置拦截器对象-->
<bean class="com.seapp.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
网友评论