springmvc
springmvc框架
1、输入地址:
2、进入web.xml
通过DispatcherServlet分发到springmvc-servlet.xml
进入controller
转发到jsp页面
直接输入去掉后jsp后缀的index
在spring-servlet.xml中配置视图解析器
在controller中写入:
Html不能像jsp一样配置,会出现404错误,在controller找不到html 的文件
2、注解
spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 自动扫描 -->
<context:component-scan base-package="controller" />
<!-- 视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp"></property>
</bean>
<!-- url对应java类的映射 -->
<!-- <bean id="simpleUrlHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index">indexController</prop>
</props>
</property>
</bean>
<bean id="indexController" class="controller.IndexController"></bean> -->
</beans>
在IndexController中用注解来替换原来的代码
@Controller
public class IndexController{
@RequestMapping("/index")
public String messagePage() {
return "index";
}
3、表单提交数据
form.jsp
<form action="/springmvc2/addPerson" method="post">
身份证:<input type="text" name="idcard"/>
姓名:<input type="text" name="name"/>
<input type="submit" value="提交"/>
</form>
IndexController.java
@RequestMapping("/addPerson")
public ModelAndView handleRequest(Person person) throws Exception {
ModelAndView mav = new ModelAndView("index");
mav.addObject("person", person) ;
return mav;
}
4、重定向
加forword和什么都不加,都是转发,重定向路径有明显变化
// 重定向
@RequestMapping("/redirect")
public ModelAndView redirect() {
ModelAndView mav = new ModelAndView("redirect:/form");
return mav;
}
5、Session
在ModelAndView中直接传入参数session
// session
@RequestMapping("/check")
public ModelAndView check(HttpSession session) {
Integer i = (Integer) session.getAttribute("count");
if (i == null)
i = 0;
i++;
session.setAttribute("count", i);
ModelAndView mav = new ModelAndView("check");
return mav;
}
6、中文乱码处理,
只需在web.xml中配置
<!-- 中文处理 -->
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
7、拦截器
filter---interceptor----controller---interceptor---filter
浏览器上的url回车后---web.xml--filter--DispatcherServlet---springmvc-servlet.xml---preHandle---controller---postHandle---afterCompletion---jsp
http://localhost:8080/springmvc/test 2,web.xml filter,dispatcherservlet
1, mvc-servlet.xml中查看扫描包--/test
和@RequestMapping("/test")和拦截规则--mvc:interceptor-/test和class="path"拦截器的路径
3,调用TestInterceptor拦截器--preHandle()
4,访问Controller--@RequestMapping("/test")public ModelAndView test()
5,test()return modelandview 6,testinterceptor--postHandle()--去找对应的页面路径
7,找到页面出现之后,调用TestInterceptor---afterCompletion()
8,调用afterCompletion(),filter,才返回resposne给浏览器,进行页面渲染
配置springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!--
如果要拦截其他路径:
/** 拦截所有
/index/** 拦截/index路径下的所有
-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/test"/>
<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
<bean class="interceptor.TestInterceptor"/>
</mvc:interceptor>
<!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>
Controller层的注解
@RequestMapping("/test")
public ModelAndView test() {
return new ModelAndView("test");
}
TestInterceptor
package interceptor;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class TestInterceptor extends HandlerInterceptorAdapter {
/**
* 在业务处理器处理请求之前被调用
* 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
* 如果返回true
* 执行下一个拦截器,直到所有的拦截器都执行完毕
* 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle(), 在访问Controller之前被调用");
return true;
}
/**
* 在业务处理器处理请求执行完成后,生成视图之前执行的动作
* 可在modelAndView中加入数据,比如当前时间
*/
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示");
modelAndView.addObject("date","由拦截器生成的时间:" + new Date().getTime());
}
/**
* 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
*
* 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
*/
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println(new Date().getTime());
System.out.println("afterCompletion(), 在访问视图之后被调用");
}
}
8、上传图片
提交后—>web.xml—>分发到springmvc-servlet.xml—>controller<—UploadImageFile—>springmvc-servlet.xml —>jsp
Upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
<form action="uploadImage" method="post" enctype="multipart/form-data">
选择图片:<input type="file" name="image" accept="image/*" /> <br>
<input type="submit" value="上传">
</form>
在springmvc中配置
<!-- 上传图片 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
通过扫描包进入controller包下的UploadController
package controller;
import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.xwork.RandomStringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import pojo.UploadedImageFile;
@Controller
public class UploadController {
/**
1. 方法的第二个参数UploadedImageFile 中已经注入好了 image
2. 通过 RandomStringUtils.randomAlphanumeric(10);获取一个随机文件名。 因为用户可能上传相同文件名的文件,
为了不覆盖原来的文件,通过随机文件名的办法来规避
3. 根据request.getServletContext().getRealPath 获取到web目录下的image目录,用于存放上传后的文件。
4. 调用file.getImage().transferTo(newFile); 复制文件
5. 把生成的随机文件名提交给视图,用于后续的显示
*/
@RequestMapping("/uploadImage")
public ModelAndView upload(HttpServletRequest request, UploadedImageFile file)
throws IllegalStateException, IOException {
String name = RandomStringUtils.randomAlphanumeric(10);// 获取随机文件名
String newFileName = name + ".jpg";
System.out.println(request.getServletContext().getRealPath("/image"));
File newFile = new File(request.getServletContext().getRealPath("/image"), newFileName);
// 当路径不存在的时候,创建该路径
newFile.getParentFile().mkdirs();
file.getImage().transferTo(newFile);
ModelAndView mav = new ModelAndView("showUploadedFile");
mav.addObject("imageName", newFileName);
return mav;
}
}
UploadedImageFile
package pojo;
import org.springframework.web.multipart.MultipartFile;
public class UploadedImageFile {
//上传文件类--springmvc定义好的
MultipartFile image;
public MultipartFile getImage() {
return image;
}
public void setImage(MultipartFile image) {
this.image = image;
}
}
showUploadedFile.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<img src="image/${imageName}"/>
9、ModelAndView返回值
/**
* 01 以前前后端不分的情况下,ModelAndView 应该是最最常见的返回值类型了, 现在前后端分离后,后端都是以返回 JSON 数据为主了。 后端返回
* ModelAndView 这个比较容易理解, 开发者可以在 ModelAndView 对象中指定视图名称,然后也可以绑定数据
*
* 返回 ModelAndView ,最常见的两个操作就是指定数据模型+指定视图名 。
*/
@RequestMapping("/book")
public ModelAndView test1() {
ModelAndView mv = new ModelAndView();
Book b1 = new Book();
b1.setId(1);
b1.setName("三国演义");
b1.setAuthor("罗贯中");
// 指定数据模型
mv.addObject("book", b1);
mv.setViewName("book");// 指定视图名
return mv;
}
10、void没有返回值
// 02 void 没有返回值,没有返回值的时候必须要带上@ResponseBody
//controller里面的void方法,不代表不往浏览器写response响应
@RequestMapping("/test2")
@ResponseBody
public void test2() {
System.out.println("test2--void,无返回值");
}
11、void实现重定向
// void 实现重定向
@RequestMapping("/test21")
@ResponseBody
public void test2_1(HttpServletResponse resp) {
resp.setStatus(302);
resp.addHeader("Location", "/springmvc/index");
}
12、void重定向的第二种写法
// 重定向的第二种写法
@RequestMapping("/test22")
@ResponseBody
public void test22(HttpServletResponse resp) {
try {
resp.sendRedirect("/springmvc/index");
} catch (IOException e) {
e.printStackTrace();
}
}
13、Void转发
// 转发
@RequestMapping("/test23")
@ResponseBody
public void test5(HttpServletRequest req, HttpServletResponse resp) {
try {
req.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
14、返回值是String类型 model 类似modelandview,map结构
//03返回值是String类型 model 类似modelandview,map结构
@RequestMapping("/hello")
public String aaa(Model model) {
model.addAttribute("username", "张三");
//redirect:hello 重定向
//forward:hello 转发
return "hello";
}
15、json实现
Springmvc-servlet.xml
<!--
自动注册
DefaultAnnotationHandlerMapping
AnnotationMethodHandlerAdapter
提供了数据绑定支持,
@NumberFormatannotation支持,@DateTimeFormat支持,
@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)
-->
<mvc:annotation-driven />
//04json实现,返回值在前后端分离的趋势下,大部分后端只需要返回 JSON 即可
/**
springmvc-servlet.xml中配置
<mvc:annotation-driven /> :
<mvc:annotation-driven /> 会自动注册
DefaultAnnotationHandlerMapping
AnnotationMethodHandlerAdapter
两个bean,这两个bean是spring MVC为@Controllers分发请求所必须的。
并提供了数据绑定支持,
@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,
读写XML的支持(JAXB),读写JSON的支持(Jackson)
需要引包
jackson-annotations.jar
jackson-core.jar
jackson-databind.jar
gson.jar or fastjson.jar
*/
@RequestMapping("/test31")
@ResponseBody
public Book test31() {
Book book=new Book();
book.setName("apple");
return book;
}
16、请求方式限制
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class MethodController {
//请求方式限制
@RequestMapping(value = "/conn", method = RequestMethod.POST)
public String postConn(@RequestParam("name") String name,Model model){
model.addAttribute("name", name+"post");
return "conntest";
}
//请求方式限制
@RequestMapping(value = "/conn", method = RequestMethod.GET)
public String getConn(@RequestParam("Name") String name,Model model){
model.addAttribute("name", name+"get");
return "conntest";
}
}