文章目录
1 响应数据和结果视图
1.1 控制器返回值类型
1.1.1 字符串类型
返回的字符串通过页面解析器进行解析跳转
@RequestMapping("/testString")
public String testString(Model model){
System.out.println("testString执行了...");
return "success";
}
1.1.2 void类型
控制器方法返回viod类型时自动默认路径下加载页面
默认路径为:WEB-INF/pages+当前虚拟路径+.jsp
多种跳转用法:请求转发、重定向、默认路径跳转
若无前两种跳转方式,则默认路径跳转
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("testVoid...");
// 请求转发
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().println("你好!");
//取消默认路径
return;
}
1.1.3 返回值为ModelAndView
ModelAndView通过addObject()方法将对象加入request域,进行请求转发
@RequestMapping("/tesModelAndView")
public ModelAndView tesModelAndView(){
ModelAndView mv = new ModelAndView();
//加入对象
mv.addObject("msg", "hello");
//设置跳转页面
mv.setViewName("success");
return mv;
}
1.2 SpringMVC的请求转发和重定向
示例代码如下:
其中,重定向时不用加上项目名称
//关键字方式转发和重定向
@RequestMapping("/testForwardOrRedirect")
public String testForwardOrRedirect(){
System.out.println("testString执行了...");
//请求转发
return "forward:/WEB-INF/pages/success.jsp";
//重定向(不用加上项目名称)
return "redirect:/index.jsp";
}
1.3 ResponseBody的用法
前期准备工作:
1.导入jquery
2.编写前端代码
3.带入json转换的jar包
导入jquery
<script src="js/jquery.min.js"></script>
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置
<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
前端代码:
<script>
//页面加载,绑定单机事件
$(function () {
$("#btn").click(function () {
//发送ajax请求
$.ajax({
//设置属性
url:"test/testAjax",
contentType:"application/json;charset=UTF-8",
data:'{"username":"张三","password":"123","age":30}',
dataType:"json",
type:"post",
success:function (data) {
//data:服务器返回数据
alert(data.username);
alert(data.password);
alert(data.age);
}
})
});
})
</script>
处理json和javaBean需要导入jar包:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
具体实现示例:
@ResponseBody加在返回值之前自动返回return后的对象
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println("testAjax...");
System.out.println(user);
//操作数据
user.setAge(1000);
//响应数据
return user;
}
2 文件上传
jar包导入
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
2.1 传统文件上传
代码实现:
@RequestMapping("/testUpload1")
public String testUpload1(HttpServletRequest request, HttpServletResponse response) throws Exception {
String path = request.getSession().getServletContext().getRealPath("/uploads/");
File file = new File(path);
//文件不存在则创建
if (!file.exists()){
file.mkdirs();
}
//获取下载器工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
for(FileItem item:items){
//判断是否为文件
if (item.isFormField()){
//普通表单类型
}else {
//文件类型
String fieldName = item.getName();
//上传
item.write(new File(path+fieldName));
//删除临时文件
item.delete();
}
}
return "success";
}
2.2 StringMVC文件上传
2.2.1 配置文件解析器对象:
<!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
2.2.2 代码实现:
参数名称须一致
@RequestMapping("/testUpload2")
public String testUpload2(HttpServletRequest request, MultipartFile upload) throws Exception {
String path = request.getSession().getServletContext().getRealPath("/uploads/");
File file = new File(path);
//文件不存在则创建
if (!file.exists()) {
file.mkdirs();
}
//文件名称
String fieldName = upload.getOriginalFilename();
//上传
upload.transferTo(new File(path + fieldName));
return "success";
}
2.3 跨服务器文件传输
导入jar包
<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>
tomcat服务器的conf/web.xml需要加入以下配置:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<!-- 此处加入--!>
<!-- 使得服务器允许文件写入。-->
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
代码实现:
@RequestMapping("/testUpload3")
public String testUpload3(HttpServletRequest request, MultipartFile upload) throws Exception {
String path = "http://localhost:9090/fileuploadServer/uploads/";
File file = new File(path);
//文件不存在则创建
if (!file.exists()) {
file.mkdirs();
}
//文件
String fieldName = upload.getOriginalFilename();
//创建服务器对象
Client client = Client.create();
WebResource resource = client.resource(path+fieldName);
//上传
resource.put(upload.getBytes());
return "success";
}
3 StringMvc异常处理
3.1 异常处理思路
Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理。
3.2处理异常
3.2.1 自定义异常类
public class SysException extends Exception {
private String message;
public SysException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3.2.2 自定义异常处理器
实现HandlerExceptionResolver接口
示例代码:
public class SysExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
Exception e = null;
//获取异常对象
if (ex instanceof SysException) {
e = (SysException) ex;
} else {
e = new SysException("系统正在维护...");
}
ModelAndView mv = new ModelAndView();
mv.addObject("errorMsg", e.getMessage());
mv.setViewName("error");
return mv;
}
}
3.2.3 配置异常处理器
<!-- 配置异常处理器 -->
<bean id="sysExceptionResolver" class="com.example.exception.SysExceptionResolver"></bean>
3.2.4 示例代码:
@RequestMapping("/testException")
public String testException() throws SysException {
try {
int i = 1/0;
}catch (Exception e){
throw new SysException("1/0");
}
return "success";
}
4 StringMvc拦截器
4.1 拦截器的概述
- SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
- 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链
中的拦截器会按着定义的顺序执行。 - 拦截器和过滤器的功能比较类似,有区别
- 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
- 拦截器是SpringMVC框架独有的。
- 过滤器配置了/*,可以拦截任何资源。
- 拦截器只会对控制器中的方法进行拦截。
- 拦截器也是AOP思想的一种实现方式
- 想要自定义拦截器,需要实现HandlerInterceptor接口
4.2 自定义拦截器
4.2.1 实现HandlerInterceptor接口
public class Interceptor1 implements HandlerInterceptor {
//执行Controller方法前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器拦截...前");
return true;
}
//执行Controller方法后
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器拦截...后");
}
//跳转页面后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("拦截器拦截...最后");
}
}
4.2.2 HandlerInterceptor接口中的方法
- preHandle方法是controller方法执行前拦截的方法
- 可以使用request或者response跳转到指定的页面
- return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
- return false不放行,不会执行controller中的方法。
- postHandle是controller方法执行后执行的方法,在JSP视图执行前。
- 可以使用request或者response跳转到指定的页面
- 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
- postHandle方法是在JSP执行后执行
- request或者response不能再跳转页面了
4.2.3 springmvc.xml 配置拦截器类
<mvc:interceptors>
<mvc:interceptor>
<!--拦截路径-->
<mvc:mapping path="/test/*"/>
<!--不拦截路径-->
<!--<mvc:exclude-mapping path=""/>-->
<bean class="com.example.interceptor.Interceptor1"></bean>
</mvc:interceptor>
可往后加入二级拦截器
</mvc:interceptors>
4.2.4 示例代码:
@RequestMapping("/testInterception")
public String testInterception(){
System.out.println("testInterception...");
return "success";
}