我的网站欢迎大家访问奥
SpringMVC基础
概述
SpringMVC是一个web层/表现层的框架,也叫MVC框架
它和Servlet的作用是一样的
SpringMVC是Spring中的一个模块,实现了MVC结构,便于简单,快速的开发MVC结构的Web程序,可以与Spring无缝集成
业务控制器的三种实现
第一种:实现Controller接口
package com.ifueen.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class HelloController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
// TODO Auto-generated method stub
System.out.println("我们不能失去信仰");
ModelAndView view = new ModelAndView();
view.addObject("name","我们不能失去信仰");
view.setViewName("/WEB-INF/test.jsp");
return view;
}
}
第二种:实现HttpRequestHandler接口
public class Controller02 implements HttpRequestHandler{
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(this.getClass());
request.getRequestDispatcher("/WEB-INF/controller.jsp").forward(request, response);
}
}
第三种:普通类加注解(常用)
package com.ifueen.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ifueen.service.HelloService;
@Controller
/*@RequestMapping("/come")*/
public class ComeController {
@Autowired
private HelloService hl;
@RequestMapping("/jack")
public void come(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
hl.eat();
req.setAttribute("jack", "哥谭市堕落了");
req.getRequestDispatcher("/WEB-INF/test.jsp").forward(req, resp);
}
}
?SpringMVC中的注解
Spring不仅支持xml配置,也支持注解配置,使用注解配置会提高开发效率
SpringMVC中控制器建议使用注解方式,是官方推荐的,外面公司也是使用此方式
实例化bean的注解
控制层注解:@Controller
业务层注解@Service
持久层注解@Repository
通用注解@Component
注意:这些注解其实是通用的,但是为了更好地区分层级关系,所以每一层都用相对应的注解,如果不知道属于哪一层,则可以用通用注解
控制器的常用操作
处理中文乱码的过滤器
由Spring提供,只需去配置一下即可
接收请求参数
通过req对象(原生的方式)
通过形参(常用)
通过对象获取(常用)
通过@PathVariable获取
/**
*第一种获取参数方式
*/
@RequestMapping("/form1")
public void form1(HttpServletRequest req,HttpServletResponse resp) {
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
System.out.println(name +"----"+ pwd);
}
/**
*第二种获取参数方式
*通过参数来接收
*/
@RequestMapping("/form2")
public void form2(String name,String pwd) {
System.out.println(name +"----"+ pwd);
}
/**
*第三种获取参数的方式
*通过对象来接收
*/
@RequestMapping("/form3")
public void form3(User user) {
System.out.println(user.getName() +"----"+ user.getPwd());
}
/**
*第四种获取参数的方式
*/
@RequestMapping("/form4/{id}")
public void form3(@PathVariable("id")Long id) {
System.out.println(id);
}
向页面传值
通过req对象(原生方式)
通过Model对象(常用)
通过ModelAndView对象
/**
*响应请求的方式一(原生方式)
*/
@RequestMapping("/form5")
public void form5(User user,HttpServletRequest req,HttpServletResponse resp) throws IOException, ServletException {
if (user.getName().equals("小丑") && "11569".equals(user.getPwd())) {
HttpSession session = req.getSession();
session.setAttribute("name", user.getName());
resp.sendRedirect("/jsp/success.jsp");
}else{
req.setAttribute("name5", user.getName());
req.setAttribute("error5", "账户或密码错误");
req.getRequestDispatcher("/jsp/model2.jsp").forward(req, resp);
}
}
/**
*响应请求的方式二(常用)
*/
@RequestMapping("/form6")
public String form6(User user,HttpServletRequest req,Model model) throws IOException, ServletException {
if (user.getName().equals("小丑") && "11569".equals(user.getPwd())) {
HttpSession session = req.getSession();
session.setAttribute("name", user.getName());
return "jsp/success";
}else{
model.addAttribute("name6", user.getName());
model.addAttribute("error6", "账户或密码错误");
return "jsp/model2";
}
}
重定向和转发
转发
SpringMVC默认转发
显示的转发方式,不会经过视图解析器
重定向
return "redirect:xx.jsp"不会经过视图解析器
/**
*两种跳转方式:重定向和转发
*/
@RequestMapping("/form8")
public String form8(User user,HttpServletRequest req,Model model) throws IOException, ServletException {
if (user.getName().equals("小丑") && "11569".equals(user.getPwd())) {
HttpSession session = req.getSession();
session.setAttribute("name", user.getName());
return "redirect:/jsp/success.jsp"; //使用重定向的方式进行跳转
}else{
model.addAttribute("name", user.getName());
model.addAttribute("error8", "账户或密码错误");
/*req.setAttribute("name", user.getName());
req.setAttribute("error8", "账户或密码错误");*/
return "forward:/jsp/model3.jsp"; //使用转发的方式进行跳转
}
}
视图解析器
通过处控制器返回的数据
如果配置了视图解析器,返回的字符串和ModelAndView会经过视图解析器
/**
*视图解析器
*/
@RequestMapping("/form9")
public ModelAndView form9(User user,HttpServletRequest req,Model model) throws IOException, ServletException {
ModelAndView maView = new ModelAndView(); //创建视图解析器对象
if (user.getName().equals("小丑") && "11569".equals(user.getPwd())) {
HttpSession session = req.getSession();
session.setAttribute("name", user.getName());
maView.setViewName("jsp/success");
return maView;
}else{
model.addAttribute("name9", user.getName());
model.addAttribute("error9", "账户或密码错误");
maView.setViewName("jsp/model4");
return maView;
}
}
SpringMVC返回Json对象
使用@ResponseBody注解,不会经过视图解析器
JSON(JavaScript Object Notation:JS对象简谱)是一种轻量级的数据格式
这种格式的数据可以用来在前后台之间做数据传递
Json表示对象:{“name”:“tom”,“age”:18}
Json表示一个集合:[{“name”:“tom”,“age”:18},{“name”:“jack”,“age”:30}]
??SpringMVC上传文件和下载
使用SpringMVC实现文件的上传Demo:
首先封装一个上传的工具类
package com.ifueen.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;
/**
*上传文件的工具类
*
*/
public class UploadUtil {
public static String upload(HttpServletRequest req,MultipartFile mFile) {
//判断上传文件是否为空
if (mFile.isEmpty()) {
return null;
}else{
//获取文件路径
String realPath = req.getServletContext().getRealPath("/uploadFile");
File file = new File(realPath);
if (!file.exists()) {
file.mkdir();
}
//处理文件名
String filename = mFile.getOriginalFilename();
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
//文件真实名字
String fname=uuid+"-"+filename;
InputStream in = null;
FileOutputStream out = null;
try {
in = mFile.getInputStream();
out = new FileOutputStream(new File(realPath,fname));
//文件拷贝
IOUtils.copy(in, out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
in.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//返回真实文件名
return fname;
}
}
}
然后写控制器
package com.ifueen.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import com.ifueen.util.UploadUtil;
@Controller
/*@RequestMapping("/come")*/
public class UploadController {
@RequestMapping("/upload")
public void upload(HttpServletRequest req,String name,MultipartFile photo) {
System.out.println(photo);
String fname = UploadUtil.upload(req, photo);
System.out.println(fname);
}
}
Jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<p>
用户名:<input type="text" name="name"/>
</p>
<p>
头像:<input type="file" name="photo"/>
</p>
<p>
<input type="submit" value="提交"/>
</p>
</form>
</body>
</html>
SpringMVC拦截器
SpringMVC拦截器和Servlet的过滤器有点相似,不同的是过滤器是针对所有拦截,而拦截器只针对请求控制器进行拦截
编写拦截器,继承HandlerInterceptor接口
package com.ifueen.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyInterceptor implements HandlerInterceptor{
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
System.out.println("响应到达页面之前拦截");
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
// TODO Auto-generated method stub
System.out.println("在控制器被调用之后拦截");
}
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("在控制器加载之前拦截");
return true;
}
}
在xml中配置
<!-- 配置拦截器组 -->
<mvc:interceptors>
<!-- 拦截器 -->
<mvc:interceptor>
<!-- 要拦截的配置 -->
<mvc:mapping path="/*" />
<!-- 设置不拦截的配置 -->
<mvc:exclude-mapping path="/login"/>
<!-- 配置拦截器 -->
<bean class="com.ifueen.interceptor.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>