Spring-MVC
- Controller(控制层)的一个框架
- SpringMVC 应当看作 Spring 的一部分 就像是spring JDBC单独的模块
流程
-
导入jar包
- spring-web-版本号.RELEASE.jar
- spring-webmvc-版本号.RELEASE.jar
-
Tomcat 核心配置web.xml
- spring-mvc会默认去到web目录下去找 请求名-servlet.xml 的 spring-MVC核心文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>请求命名</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--加载的类--> <!--初始化时将spring核心配置文件指向自己设定的文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:ApplicationContext.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>请求命名</servlet-name> <url-pattern>*.do</url-pattern> <!--拦截的请求--> </servlet-mapping> </web-app> -
Spring-MVC核心配置
-
将Controller 对象交由spring容器管理
-
方式一:
-
<!--<bean id="ID名" class="包名.类名"></bean>-->
-
-
方式二:
-
<context:component-scan base-package="controller"></context:component-scan> 扫包 -
@Controller public calss TetsController(){ public void test(){ System.out.print("controller测试") } }
-
-
-
配置真实的请求和类对应关系
-
方式一:
-
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping> <property name="mappings"> <props> <prop key="请求名.do">对应的类名</prop> </props> </property> </bean>
-
-
方式二
-
<mvc:annotation-driven> </mvc:annotation-driven> <!--开启注解驱动 相当于是加载了HandlerMapping类对象--> -
@RequestMapping("请求名.do") public class TestController { @RequestMapping public String test(){ System.out.println("成功"); return "weclome.jsp"; } }
-
-
接收请求
如何接收请求
方式一
//直接写在类上 @RequestMapping("请求名.do") public class TestController { @RequestMapping() public String test(){ System.out.println("成功"); return "weclome.jsp"; } }方式二
-
<!--发送请求-->
<a href="url:端口号/请求?method=请求的方法名&参数1=test1,参数2=test2">
// 接收请求
@RequestMapping("请求名.do")
public class TestController{
@RequestMapping(parame={"参数1","参数2"})
public String test(){
System.out.print("Hello Word")
}
}
方式三
请求方式同上
public class TestController{
直接在方法上写该注解
@RequestMapping("请求.do",parame={"参数1","参数2"})
public void test(){
System.out.print("Hello Word")
}
}
方式三
//将接收的参数,组成集合 list,map等
//map需要前面加上注解 @RequestParam
//其他集合正常写即可
@RequestMapping(path = "testThree.do",method = RequestMethod.GET)
public String testThree(@RequestParam Map map){
System.out.println(map.get("user"));
System.out.println(map.get("pass"));
return "weclome.jsp";
}
RequestMapping 解析
path={"",""} //填写请求
value={"",""} //填写值
params={"",""} //定义传递的参数名字
method={RequestMethod.GET} //定义接收的请求方式
GET,
HEAD,
POST,
PUT,
PATCH,
DELETE,
OPTIONS,
TRACE;
headers={"Accept-Language",""} //获取请求头
中文乱码
方式一
<!--在请求时后台输出会出现乱码,可在配置文件添加拦截器,交由springMVC解析-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
相关注解
@RequestBody //获取请求的主体
@CookieValue //获取请求的cookie
@RequestHeader //获取请求头
@ModelAttribute("请求名.do") //可以立即为请求初始化
@RequestMapping("请求名.do")
public String testParam1(@RequestBody String body, @CookieValue("JSESSIONID") String cookieValue, @RequestHeader("Accept-Language")String header){
//请求(参数) domain 控制层 业务层 持久层 domain(属性-数据库中列) JDBC-->数据库
System.out.println("参数的测试方法");
System.out.println("接收到的body:"+body);
System.out.println("接收到的header:"+header);
System.out.println("接收到的cookie:"+cookieValue);
return "weclome.jsp";
}
@ModelAttribute("想要拦截的请求")
public void testModel(){
System.out.print("我是提前的方法")
}
响应
原生
只能自己通过原生response获取输出流 回写响应信息
//void表示不需要框架帮我们处理响应信息
public void testReponse(HttpServletResponse response){
//将数据返回给浏览器
response.getWrite().write("要响应的内容")
// 转发:
requet.getRequestDispatcher().forward(requset,response);
// 重定向:
response.sendReddirect();
}
框架
// String(没有@ResponseBody注解)
// 表示请求框架帮我们处理响应信息路径的转发或重定向
//forward:
//redirect:
public String testRepsone(){
//转发
return "redirect:资源"
//重定向
return "forward:资源"
//默认不写即为转发
return "资源"
}
异步请求
//通常发送异步请求 map domain list set
// 需要导入json相关的包(core databind annotations)
//并在方法上添加@Responsebody
//完成上述步骤,框架会自动将你想传递的值转换为json形式
@ResponseBody
@RequestMapping("response.do")
public Map<String,String> testResponse(@RequestBody Student student){
System.out.println("我是接收的用户名"+student.getUser());
System.out.println("我是接收的密码"+student.getPass());
Student student1=new Student("lll",1);
//domain (存储一对数据的容器,但是比map更具体)
Student student1=new Student();
student.setUser("lym");
student.setpass(123);
return student1;
//Map (集合,存放一堆相同格式的容器) 方式 其他集合只用正常放入集合中,正常返回就好
HashMap<String,String> map=new HashMap<String, String>();
map.put("aaa","a1");
map.put("bbb","b2");
map.put("ccc","c3");
return map;
}
前端(如:浏览器)传json
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<script type="text/javascript">
function Person(){}
window.onload = function () {
//找到按钮DOM对象 绑定单击事件
document.getElementById("button").onclick = function () {
//1.创建一个AJAX对象用于发送
var xhr = new XMLHttpRequest();
//2.打开一个通道 模拟一个请求 ("请求方式","请求URL",是否为异步true)
xhr.open("POST","response.do?,true);
// 2.1如果想要发送的是json形式 告知浏览器解析的时候规则
xhr.setRequestHeader("Content-type","application/json;charset=UTF-8");
//3.发送后 时刻监听者服务端的状态 回调机制
xhr.onreadystatechange = function () {
if(xhr.readyState==4 && xhr.status==200){
//接收响应信息啦
alert(xhr.responseText);
//接收以后 需要处理 展示在浏览器中的某个组件里
}
}
//4.发送请求
xhr.send('{"user":"张三","pass":123}');
}
}
</script>
<body>
<input id="button" type="button" value="测试JSON形式">
</body>
</html>
// 发送端设置JSON形式
// 接收端(服务端的方法) 参数上面@RequestBody即可 domain对象接收
@ResponseBody
@RequestMapping("response.do")
public void testResponse(@RequestBody Student student){
System.out.print(student.getUser);---> 输出结果:张三
System.out.print(student.getPass);---> 输出结果:123
}
ModelAndView
利用控制层的方法返回值来处理响应
1.void 不用框架帮我们处理 需要自己处理 response.getWriter() write()
2.String 让框架帮我们去做转发、重定向 String----资源名字
forward: redirect:
3.Object domain String Map List----->JSON
1.处理工具---jar
2.告知框架方法的返回值需要解释 @Responsebody
4.ModelAndView
存储信息
转发的路径
服务端业务层可能会产生一些数据
这些数据我们需要存入作用域中带走
request.setAttribute();
1.可以利用原生Map来处理
Map接收请求参数(@RequestParam)
Map可以返回数据(@ResponseBody)
2.可以利用Model 或 ModelMap
Model底层继承ModelMap
存储数据之前不需要自己创建
只需将变量放置在方法的参数里即可 框架会帮我们自动注入
m.addAttribute("",object);
但是只能存储数据
不能携带转发的路径资源
对象不需要返回
public void Login(User user, Model model,ModelMaP map){
model.addAttribute("object","test");
modelMap.addAllAttributes(Map<T> attributes)
}
3.可以利用ModelAndView
不能放在方法的参数里 框架不会帮我们注入
需要用的时候 自己new即可
mv.addObject("key",object);
mv.setViewName("xxx.jsp");
可以包含数据和转发路径
需要将自己创建的mv对象返回
public ModelAndView Login(User user){
ModelAndView mv=new ModelAndView();
System.out.println("这是model"+model);
mv.addAttribute("modelUser",user);
mv.addObject("madUser",user);
return mv;
4.如果想要将值存入session作用域范畴内
需要在类名上面添加注解
@SessionAttributes({"key","",""})
捕获异常
第一步
//定义实现springMvc提供的接口
public class ExeptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
if (e instanceof MyExeption){
ModelAndView mav=new ModelAndView();
mav.addObject("err",e.getMessage());
mav.setViewName("err.jsp");
return mav;
}
return null;
}
}
第二步
//描述一个异常
//继承java 运行时异常
public class MyExeption extends RuntimeException {
//描述的错误
private String message;
public MyExeption(){}
public MyExeption(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
测试类
@ResponseBody
@Controller
public class TestEer {
private ModeService service;
@RequestMapping(path = "rex.do")
public String testReception() {
// ModelAndView mav=new ModelAndView();
System.out.println("controller执行啦");
//1.字符集
//2.接收参数(参数列表)
//3.找寻业务层方法处理逻辑------>可能会产生异常
try {
String s = null;
s.length();
//s.length();//NullPointerException
} catch (Exception e){
e.printStackTrace();//打印后台开发人员可以看到 异常记录在文件 日志
throw new MyExeption("错误页面");
}
//4.正常的响应
return "err.jsp";
}
}
上传下载
@Controller
public class Upload {
@RequestMapping("upload.do")
// String text, MultipartFile upload
public String upload(String text, MultipartFile upload) throws IOException {
System.out.println("测试成功");
System.out.println(text);
System.out.println(upload);
String fileName=upload.getOriginalFilename();
upload.transferTo(new File("D://File/",fileName));
return "weclome.jsp";
}
@RequestMapping("download.do")
public ResponseEntity<byte[]> download(String fileName) throws IOException {
//获取读取文件即可
File file=new File("D://File/"+fileName);
//设置响应相关信息
//如果有中文 需要处理
fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
HttpHeaders headers=new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment",fileName);
//将响应信息存入一个返回值对象内即可----ResponseEntity
byte[] b= FileUtils.readFileToByteArray(file);
return new ResponseEntity(b,headers, HttpStatus.CREATED);
}
}
配置文件
//设置读取的文件数
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10244000"></property>
</bean>
notepad++ 官网: notepad-plus-plus.org/