目录
1.通过testModelAndView对象 实际上是将数据绑定到了request域对象身上
创建工程
1.创建maven工程
2,导入pom依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
3.配置web.xml文件
代码功能解释:
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>//寻找带注解的 //请求来时初始化spring-mvc文件 原来该DispatcherServlet默认使用WebApplicationContext作为上下文,Spring默认配置文件为“/WEB-INF/[servlet名字]-servlet.xml”。 <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern>//拦截所有请求 </servlet-mapping>
4.在spring-mvc配置视图解析器
Spring 默认提供了多种视图解析器,比如,我们可以使用最常用解析器 InternalResourceViewResolver 来查找 JSP 视图(与之相对应的视图类为 InternalResourceView)。
<!--视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean>
5.在spring-mvc 配置ioc容器
只能扫描controller的注解
<context:component-scan base-package="com.buka.edu" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
从前台获取数据的几种方式
1.基础的
@RequestMapping("/hello/*/abc") public String test2(){ return "hello"; }
@RequestMapping("/hello/*/abc"):*号可以任意,但是不能hello/user/loo/abc这种形式
@Controller @RequestMapping("/user") public class UserController { @RequestMapping(value = "/hello" ,method = RequestMethod.GET,params = {"name","password2!=0"}) public String Hello() { System.out.println("111111"); return "hello"; }
@RequestMapping("/user"):一个类中所有的方法上的请求前都有user这个请求
@RequestMapping(value = "/hello" ,method = RequestMethod.GET,params = {"name","password2!=0"}):value是请求名字,method是请求类型,get请求,params设置属性的个数和条件
return "hello";:相当于转发走视图解析器:
/WEB-INF/views/hello.jsp
2.接受请求来的id类似属性
@RequestMapping(value = "/test/{id}" ) public String test(@PathVariable("id") Integer id) { System.out.println(id); return "hello"; }
@PathVariable("id") Integer id:接受请求来的id,赋值给方法参数id。
3,接受jsp页面的form请求的属性
方式1:
@RequestMapping(value = "/test1") public String test1(@RequestParam("name") String name ,@RequestParam(value = "password" ,required = false,defaultValue = "1") String password) { System.out.println(name+password); return "hello"; }
@RequestParam("name")里面的属性名字要与form里的相同
方式2:
.创建实体类保证属性与form请求的属性名字相同,后台直接用属性接受,不需要注解
@RequestMapping("/testPOJO") public String testPOJO(String name,String age){ System.out.println(name+";;"+age); return "hello"; }
mvc可以联级
<form action="user/testPOJO" method="get"> <input type="text" name="name"><br> <input type="text" name="age"><br> <input type="text" name="car.kind"> <input type="submit" value="testPOJO"> </form>
4.请求类型转换
浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求,该过滤器为HiddenHttpMethodFilter。
HiddenHttpMethodFilter的父类是OncePerRequestFilter,它继承了父类的doFilterInternal方法,工作原理是将jsp页面的form表单的method属性值在doFilterInternal方法中转化为标准的Http方法,即GET,、POST、 HEAD、OPTIONS、PUT、DELETE、TRACE,然后到Controller中找到对应的方法。例如,在使用注解时我们可能会在Controller中用于@RequestMapping(value = "list", method = RequestMethod.PUT),所以如果你的表单中使用的是<form method="put">,那么这个表单会被提交到标了Method="PUT"的方法中。
配置过滤器
<!-- <filter>--> <!-- <filter-name>HiddenHttpMethodFilter</filter-name>--> <!-- <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>--> <!-- </filter>--> <!-- <filter-mapping>--> <!-- <filter-name>HiddenHttpMethodFilter</filter-name>--> <!-- <url-pattern>/*</url-pattern>--> <!-- </filter-mapping>-->
jsp页面
<input type="hidden" name="_method" value="PUT">:将要被转换的请求
<form action="user/testPut/1" method="post"> <input type="hidden" name="_method" value="PUT"> <input type="text" name="name"><br> <input type="text" name="age"><br> <input type="submit" value="testPut"> </form> <br> <form action="user/testDelete/1" method="post"> <input type="hidden" name="_method" value="DELETE"> <input type="text" name="name"><br> <input type="text" name="age"><br> <input type="submit" value="testDelete"> </form>
controller类:
@RequestMapping(value = "/testPut/{id}",method = RequestMethod.PUT) public String testPut(@PathVariable("id")Integer id){ System.out.println(id); return "hello"; } @RequestMapping(value = "/testDelete/{id}",method = RequestMethod.DELETE) public String testDelete(@PathVariable("id")Integer id){ System.out.println(id); return "hello"; }
后台数据发送到前台几种方式
1.通过testModelAndView对象 实际上是将数据绑定到了request域对象身上
@RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ ModelAndView modelAndView=new ModelAndView("hello"); modelAndView.addObject("abc","123"); return modelAndView; }
2,通过map存储也能发送到前台
@RequestMapping("/testMap") public String testMap(Map<String ,String> map){ map.put("abc","wwww"); return "hello"; }
jsp页面显示
request:${requestScope.user} <br> request:${requestScope.abc}
值得注意的是:
在JSP 2.0中,建议尽量使用EL而使JSP的格式更一致。 在web.xml的<jsp-property-group>中可以控制一组JSP是否使用EL,在每个JSP中也可以指定是否该JSP使用EL。
在page directive中的isELIgnored属性用来指定是否忽略。格式为: <%@ page isELIgnored="true|false"%> 如果设定为真,那么JSP中的表达式被当成字符串处理。比如下面这个表达式${2000 % 20}, 在isELIgnored="true"时输出为${2000 % 20},而isELIgnored="false"时输出为100。Web容器默认isELIgnored="false
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
3.通过@ModelAttribute注解
@ModelAttribute:访问testAttributiong方法之前 会先将map里面key的值和testAttributiong的参数名相同的数据复制给 参数然后前台过来的数据会 把 方法参数的属性修改
@RequestMapping("/testAttributiong") public String testAttributiong(User user){ System.out.println(user); return "hello"; }
@ModelAttribute public void test(Map<String,User> map){ System.out.println("111111111111111111111"); //假设是从数据库里面查询出来的 User user=new User(); user.setAge(18); user.setName("tom"); map.put("user",user); }
4.通过@SessionAttributes 注解
@SessionAttributes 这个标签是标注在类的上面的,作用是将数据放到session里面
@SessionAttributes(value = {"user"},types = {String.class})
方法:将相同的key的value值赋值给session对象的key的value值
@RequestMapping("/testSessionAttributes") public String testSessionAttributes(Map<String,Object> map){ User user=new User(); user.setName("tom"); user.setAge(10); map.put("user",user); map.put("abc","123"); return "hello"; }
页面获取
sessionScope:${sessionScope.user}
5.转发和重定向的区别
1.重定向的特点:
(1)重定向是有两个请求的
(2)重定向不支持serlvet共享,如果设置了request.setAttribute变量,则全部消失
(3)重定向浏览器上面url地址发送了变化
@RequestMapping("/redirectAction.shtml")
public String redirectAction(HttpServletResponse response) {
//return response.sendRedirect("index.shtml"); (第一种)
return "redirect:/index.shtml"; //(第二种)
}
2.转发特点:
(1)url地址不变
(2)原先的serlvet还可以共享
(3)转发只能在组件内转发
@RequestMapping("/testForword") public String testForword(){ return "forward:/user/testMap"; 或者 return request.getRequestDispather("user/testMap").forward(request,response);}
6.自定义类型转换
第一步:实现接口:
public class ConverterMySelf implements Converter<String, Date> {//把字符串转化成date @Override public Date convert(String s) { System.out.println("11111111"); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");//只能转化这样格式的字符 Date date=null; try { date=sdf.parse(s);//转化成date } catch (ParseException e) { e.printStackTrace(); } return date; } }
第二步:配置springmvc
<bean id="converterService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.buka.edu.controller.ConverterMySelf"></bean> </list> </property> </bean> <mvc:annotation-driven conversion-service="converterService"/>
第三步:写controller接受数据
@RequestMapping("/test6") public String test6(Date date) { System.out.println(date); return "hello"; }
怎么样把date转成字符呢
SimpleDateFormat format0 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = format0.format(ss.getTime());//这个就是把时间戳经过处理得到期望格式的时间
7.文件上传
第一步:导入依赖
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency>
第二步:写jsp页面
<form action="user/upload" method="post" enctype="multipart/form-data"> <input type="file" name="file"><br> <input type="file" name="file"><br> <input type="file" name="file"><br> <input type="submit" value="上传"> </form>
注意要在form标签中加上enctype="multipart/form-data"表示该表单是要处理文件的,这是最基本的东西,很多人会忘记然而当上传出错后则去找程序的错误,却忘了这一点。
@RequestParam("file")要注意,要不然接收不到
第三步:写controller控制层
当上传多个文件时
@RequestMapping("/FILE") public String test10(@RequestParam("file") MultipartFile [] files)//接受数组 { for(int i=0;i<files.length;i++) { if(files[i]!=null) { test7(files[i]);//一个一个上传 } } return "hello"; } public boolean test7(MultipartFile file) { System.out.println(file); String originalFilename = file.getOriginalFilename();//得到图片名字 try { file.transferTo(new File("d://"+originalFilename));// } catch (IOException e) { e.printStackTrace(); } return true; }
8.json格式传输数据
第一步:导入依赖
<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-annotations</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency>
第二步:配置xml
方式一:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> </bean> </list> </property> </bean>
方式二:添加注解驱动
<mvc:annotation-driven/>
就不用使用类方法了
第三步:写controller层
@ResponseBody:加上他,返回的才是json格式的字符串
@RequestMapping("/testString") @ResponseBody public User testString() throws JsonProcessingException { User user = new User(); user.setName("tom"); user.setAge(18); // ObjectMapper objectMapper = new ObjectMapper();//导包的目的,调用类里的方法转化成json字符串 // String s = objectMapper.writeValueAsString(user); return user;//返回前端页面 一个hello字符串 }
第三步:配置编码过滤器
注意:配置过滤器的时候 过滤器一定要配置在最前面
代码:
<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>//设置utf-8 </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
9.拦截器的使用
拦截器类似于servlet过滤器,不同的是,拦截器只会拦截控制方法,不会拦截jsp,html页面,js,一般是做验证用 登录或者权限
第一步:写HandlerInterceptor的实现类
return true;代表放行
return false 代表拦截
public class HandlerInterceptorTest implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("1111111111111"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { System.out.println("2222222222222"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { System.out.println("333333333333"); } }
第二步:写登录的jsp页面
<form action="/newspringmvc_war_exploded/user/login" METHOD="post"> username:<input type="text" name="username"><br> password:<input type="text" mame="password"><br> <input type="submit" value="登录"> </form>
第二步:写controller层
通过session来绑定数据
@RequestMapping("/login") public String testlogin(User2 user, HttpServletRequest request){ //用户名张三 密码123456 HttpSession session=request.getSession(); session.setAttribute("user",user); return "hello"; }
第三步:实现拦截方法
User2 user=(User2) request.getSession().getAttribute("user");//获取user的值 if(user==null){ //没有登录 没有登录我就让你跳转到登录页面 request.setAttribute("message","请登录");//绑定信息,放在登录页面 request.getRequestDispatcher("/index.jsp").forward(request,response); }else{ return true; } return true;
第四步:完善登录页面
<h2><span style="color: red">${message}</span></h2>
放在登录的上面,如果走拦截器中的user值为空,message就会被赋予值,否则不会显示