MVC是什么?
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
模型(Model) :模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑。
视图(View) :视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面。
控制器(controller) :控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态。
MVC 式的出现不仅实现了功能模块和显示模块的分离,同时它还提高了应用系统的可维护性、可扩张性、可移植性和组件的可复用性。
Spring MVC是什么?
在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,是为了简化开发,减少出错。还是为了组内开发人员之间的配合。总之就是一种分层工作的办法。
spring mvc(注解方式)
//Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<-- 默认为springmvc-servlet.xml 可以修改成自定义 -->
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
//根据 web.xml的配置文件加载springmvc.xml
//springmvc.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">
<!--spring的扫描器实现bean的自动载入-->
<context:component-scan base-package="Controller" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
//controller
@Controller
public class controller {
@RequestMapping("/index")
public ModelAndView handleRequest(
HttpServletRequest request, HttpServletResponse response) {
ModelAndView mav = new ModelAndView("index");
mav.addObject("obj", "Hello Spring MVC");
return mav;
}
}
//启动tomcat 运行http://localhost:8080/index
输出:Hello Spring MVC
接受表单参数
//pojo
public class Product {
private int id;
private String name;
private float price;
//set get..
// 在web文件下先做一个直接可以显示.jsp
<form action="addProduct"> //提交表单
产品名称:<input type="text" name="name"><br>
产品价格:<input type="text" name="price">
<input type="submit" value="增加商品">
</form>
//ProductController
@Controller
public class ProductController {
@RequestMapping("/addProduct")
public ModelAndView add(Product product) {
ModelAndView mav = new ModelAndView("showProduct");
mav.addObject("p", product);
return mav;
}
}
在WEB-INF/page下创建
//showProduct
产品名称: ${p.name}<br>
产品价格: ${p.price}
Springmvc客户端跳转
上面的例子都是将的服务端跳转,这时说的是客户端跳转
那什么是服务端跳转和客户端跳转呢?
客户端跳转时用HttPservletResopse对象的sendRedirect函数实现,服务器端跳转是使用RequestDispather对象的forward方法实现的。
客户端跳转:服务器端将请求结果返回给客户端,客户端向服务器发出另一次请求。在客户端跳转过程中是两次不同的请求。在地址栏中显示的是最后一次请求地址。
因为地址栏显示的是重定向后的url,所以只会执行后面的url映射的控制器.
服务器端跳转(容器内跳转):能够自动的在服务器内部进行跳转,这种跳转对用户来说是透明的。两次跳转时同一个request,在地址栏中显示的事第一次页面地址。
因为是同一个request,拦截器只会拦截前一个url,如果前一个url在
映射时未配置到拦截器拦截,则拦截后一个url,即只拦截一次;
因为地址栏显示的是转发前的url,所以会依次执行前后两个控制器.
//redirect
@Controller
public class ProductController {
@RequestMapping("/addProduct")
public ModelAndView add(Product product) {
ModelAndView mav = new ModelAndView("redirect:/showProduct");
mav.addObject("p", product);
return mav;
}
@RequestMapping("/showProduct")
public ModelAndView show(Product product) {
ModelAndView mav = new ModelAndView("showProduct");
return mav;
}
}
//访问http://localhost:8080/addProduct.jsp 并提交数据
//因为使用了"redirect:/showProduct"
//此时地址栏是http://localhost:8080/showProduct
产品名称:
产品价格:
为什么输出是空白呢?
因为地址栏显示的是重定向后的url,所以只会执行后面的url映射的控制器
//forward
//基于上面例子
@Controller
public class ProductController {
@RequestMapping("/addProduct")
public ModelAndView add(Product product) {
ModelAndView mav = new ModelAndView("forward:/showProduct");
mav.addObject("p", product);
return mav;
}
@RequestMapping("/showProduct")
public ModelAndView show(Product product) {
ModelAndView mav = new ModelAndView("showProduct");
return mav;
}
}
//因为使用了"forward:/showProduct" 转发
//会执行两个控制器(/addProduct、/showProduct)
//访问http://localhost:8080/addProduct.jsp 并提交数据
//地址栏显示的是转发前的url
//此时地址栏http://localhost:8080/addProduct?name=X&price=1
产品名称: X
产品价格: 1
springmvc使用session
Session在用户登录,一些特殊场合在页面间传递数据的时候会经常用到
//controller
@RequestMapping("/check")
public ModelAndView check(HttpSession session) {
ModelAndView mav = new ModelAndView("check");
Integer count = (Integer) session.getAttribute("count");
if (count == null) {
session.setAttribute("count", 1);
} else {
session.setAttribute("count", ++count);
}
return mav;
//check.jsp
访问次数:${count}
//每刷新一次 count+1
springmvc处理中文问题
<!--处理中文问题-->
<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>
//提交数据
<form action="addProduct" method="post"> //添加post请求
产品名称:<input type="text" name="name"><br>
产品价格:<input type="text" name="price">
<input type="submit" value="增加商品">
</form>
Springmvc上传文件
首先,之前我们配置web.xml拦截了所有的请求。
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
我们要上传文件都会被拦截。所以我们有两种处理方式:
第一种: DispatcherServlet拦截".do"这样的有后缀的URL,就不存在访问不到静态资源的问题。
第二种:如果你的DispatcherServlet拦截"/",为了实现REST风格,拦截了所有的请求,那么同时对.js,.jpg等静态文件的访问也就被拦截了。所以要在web.xml配置。
//web.xml
//这个必须在springmvc的servlet之前配置
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
这里的例子采用第二种方式演示
//web.xml
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<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>
//配置springmvc-servlet.xml
<!--spring的扫描器实现bean的自动载入-->
<context:component-scan base-package="Controller" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--开放对文件上传支持-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
//upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*" isELIgnored="false" %>
// 上传图片表单 method="post"和enctype="multipart/form-data" 缺一不可
<form action="uploadImage" method="post" enctype="multipart/form-data">
//上传组件 增加 accept="image/*" 表示只能选择图片进行上传
选择图片:<input type="file" name="image" accept="image/*"><br>
<input type="submit" value="上传">
</form>
//pojo类
public class UploadedImageFile {
//用于接受页面的注入,字段image必须和上传页面upload.jsp中的name=image一致
MultipartFile image;
public MultipartFile getimage(){
return image;
}
public void setImage(MultipartFile image){
this.image = image;
}
}
//Controller
@Controller
public class UploadController {
@RequestMapping("/uploadImage")
public ModelAndView upload(UploadedImageFile image, HttpServletRequest request) throws IOException {
//生成一个随机名
String name = RandomStringUtils.randomAlphabetic(10);
String newFileName = name+ ".jpg";
//获取到web目录下的image目录
File newFile= new File(request.getServletContext().getRealPath("/image"),newFileName);
//调用getParentFile()获得父目录,用.mkdirs()生成父目录文件夹
newFile.getParentFile().mkdirs();
//把内存图片写入磁盘中(写入图片)
image.getimage().transferTo(newFile);
ModelAndView mav = new ModelAndView("showUploadedFile");
mav.addObject("imageName",newFileName);
return mav;
}
}
//showUploadedFile
<img src="image/${imageName}"/>
//图片缓存在out下