1、什么是三层架构?
-
我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就
是浏览器服务器。在 JavaEE 开发中,几乎全都是基于 B/S架构的开发。那么在 B/S架构中,系统标准的三层架构
包括:表现层、业务层、持久层。三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于
三层架构设计的。
三层架构中,每一层各司其职,接下来我们就说说每层都负责哪些方面: -
表现层:
也就是我们常说的web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求
web 层,web 需要接收 http 请求,完成 http 响应。
表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。
表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。
表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系) -
业务层:
也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web 层依赖业
务层,但是业务层不依赖 web 层。
业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的,
事务应该放到业务层来控制) -
持久层:
也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进
行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库
中。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的。 -
三层架构的优点:
-
1、结构更加的明确,各层只需专注于自己的事情
-
2、表示层只和业务逻辑层有联系,提高了数据安全性
-
3、有利于系统的分散开发,每一个层可以由不同的人员来开发,只要遵循接口标准
-
4、利于各层逻辑的复用
-
2、什么是MVC 模型?
-
MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,
是一种用于设计创建 Web 应用程序表现层的模式。MVC 中每个部分各司其职 -
Model (模型) :模型,英文是Model。也就是指POJO(JavaBean)
-
View (视图) :
通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。
通常视图是依据模型数据创建的。 -
Controller (控制器) :
是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。
它相对于前两个不是很好理解,这里举个例子:
例如:
我们要保存一个用户的信息,该用户信息中包含了姓名,性别,年龄等等。
这时候表单输入要求年龄必须是 1~100 之间的整数。姓名和性别不能为空。并且把数据填充
到模型之中。
此时除了 js 的校验之外,服务器端也应该有数据准确性的校验,那么校验就是控制器的该做
的。
当校验失败后,由控制器负责把错误页面展示给使用者。
如果校验成功,也是控制器负责把数据填充到模型,并且调用业务层实现完整的业务需求。
3、Spring MVC是什么?
- Spring web mvc是表现层的框架,它是Spring框架的一部分,我们可以从Spring的整体结构中看得出来。
4、Spring MVC处理流程是什么?
4.1处理流程图解
4.2步骤说明
-
1.用户发送请求至前端控制器
-
2.前端控制器收到请求,调用处理器映射器
-
3.处理器映射器根据请求url查找处理器,返回给前端控制器
-
4.前端控制器通过处理器适配器调用处理器
-
5.执行处理器
-
6.执行完成返回ModelAndView
-
7.处理器适配器将执行结果返回前端控制器
-
8.前端控制器调用视图解析器
-
9.视图解析器返回具体View
-
10.前端控制器对View进行渲染视图
-
11.前端控制器响应用户
4.3组件说明
-
1、DispatcherServlet:
- 前端控制器:
用户请求到达前端控制器,它就相当于mvc模式中的C。 dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的求,它的存在降低了组件之间的耦合性。
- 前端控制器:
-
2、HandlerMapping:
- 处理器映射器 :
HandlerMapping负责根据用户请求找到Handler即处理器。 springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
- 处理器映射器 :
-
3、Handler:
- 处理器:
Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
-
4、HandlAdapter:
- 处理器适配器 :
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
- 处理器适配器 :
-
5、View Resolver:
- 视图解析器:
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。
- 6、View:
- 视图 :
springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。
- 视图 :
5、WebApplicationInitializer有什么作用?
5.1作用
- 现在JavaConfig配置方式在逐步取代xml配置方式。而WebApplicationInitializer可以看做是Web.xml的替代,它是一个接口。通过实现WebApplicationInitializer,在其中可以添加servlet,listener等,在加载Web项目的时候会加载这个接口实现类,从而起到web.xml相同的作用。
5.2代码示例
package com.czxy.init;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class WebInitializer implements WebApplicationInitializer {
public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {
1.初始化 Spring 容器
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(SpringMvcConfig.class);
applicationContext.setServletContext(servletContext);
//2.设置springmvc前端控制器
ServletRegistration.Dynamic ds = servletContext.addServlet("springmvc", new DispatcherServlet(applicationContext));
ds.addMapping("/");
ds.setLoadOnStartup(2);
//3 post乱码配置
FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("CharacterEncodingFilter", new CharacterEncodingFilter("UTF-8"));
encodingFilter.addMappingForUrlPatterns(null, true, "/*");
}
}
6、如何配置视图解析器?
6.1作用
- 有些时候页面放置的位置存在多级文件夹,在SpringMVC中写跳转路径的时候总是会写很长,这样很不方便。有了SpringMVC的视图解析器就可以定义好页面路径的前缀(文件夹路径)和后缀(页面格式,jsp;html…),在书写路径的时候只需要写对应页面名字就可以了,着实提高了开发效率。
6.2代码示例
package com.czxy.init;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@ComponentScan("com.czxy")
public class SpringMvcConfig {
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
7、springmvc支持哪几种类型的参数绑定?
7.1默认支持的类型
-
说明:处理器方法形参中添加如下类型的参数,处理适配器会默认识别并进行赋值 。
-
1、HttpServletRequest :通过request对象获取请求信息
-
2、HttpServletResponse :通过response处理响应信息
-
3、HttpSession :通过session对象得到session中存放的数据
-
4、Model/ModelMap :
-
-
ModelMap是Model接口的实现类,通过Model或ModelMap向页面传递数据。
-
使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap。 注意事项: 其本质都是使用Request对象向jsp传递数据。
示例:
@RequestMapping("/itemEdit")
public String editItem( HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) {}
7.2简单类型
-
说明:当请求的参数名称和处理器方法形参名称一致时,会 将请求参数与形参进行绑定 。
-
整形:Integer、int
-
字符串:String
-
单精度:Float、float
-
双精度:Double、double
-
布尔型:Boolean、boolean
-
7.3pojo类型
- 说明:当请求参数过多时,可以采用pojo接受参数, 要求参数名称和pojo属性名称一致 。
示例:
//JavaBean定义
public class Items {
private String name;
private Float price;
}
//前台表单
商品名称<input type="text" name="name" /> <br/>
商品价格<input type="text" name="price" />
//后台
@RequestMapping("/updateitem")
public String updateItem(Items items) { }
- 注意事项:默认只支持简单数据类型,日期类型需要用到转换器
7.4包装pojo
示例:
//JavaBean
public class QueryVo {
private Items items;
public Items getItems() { return items; }
public void setItems(Items items) { this.items = items; }
}
//前台
商品名称: <input type="text" name="items.name"/> <br/>
商品id: <input type="text" name="items.price"/>
//后台
@RequestMapping("/queryitem")
public String queryItem(QueryVo queryVo) { }
7.5数组
示例:
//前台
<input type="checkbox" name="ids" value="1">
<input type="checkbox" name="ids" value="2">
//包装类
public class QueryVo {
private String[] ids;
}
//后台
@RequestMapping("/queryitem")
public String queryItem(QueryVo queryVo, String[] ids) { return "success"; }
- 注意事项:Controller方法中可以用String[]接收,或者pojo的String[]属性接收。
7.6List
- 示例:
//包装类
public class QueryVo {
private List<Items> itemList;
}
//前端页面
<c:forEach items="${itemList }" var="item" varStatus="s">
<tr> <td> <input type="hidden" name="itemList[${s.index}].id" value="${item.id }"> <input type="text" name="itemList[${s.index}].name" value="${item.name }"> </td> <td><input type="text" name="itemList[${s.index}].price" value="${item.price }"></td> </tr>
</c:forEach>
name属性必须是包装pojo的list属性+下标+元素属性。
8、@RequestParam 注解有什么作用?
- 当请求的参数名称和处理器方法形参名称不一致时使用
9、@RequestMapping 注解有什么作用?
-
1.URL路径映射
-
2.窄化请求映射
- 在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。
-
3.请求方法限定
-
限定GET方法 @RequestMapping(method = RequestMethod.GET)
-
限定POST方法 @RequestMapping(method = RequestMethod.POST)
-
GET和POST都可以 @RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
-
-
注意:设置限定请求方法后,请求方式不匹配会抛异常
10、controller方法返回值类型有哪些?
- 1、返回ModelAndView
//controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。
@RequestMapping("/itemList")
public ModelAndView getItemList() throws Exception {
List<Items> itemList = itemService.getItemList();
ModelAndView modelAndView = new ModelAndView();
//把结果传递给页面
modelAndView.addObject("itemList", itemList);
//设置逻辑视图
modelAndView.setViewName("itemList");
//返回结果
return modelAndView;
}
-
2、返回void
- 如果方法返回void,有3种情况:request请求转发、response重定向、ajax
@RequestMapping("/itemList2")
public void itemList2(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.getRequestDispatcher("/WEB-INF/jsp/itemList.jsp").forward(request, response);*/ PrintWriter writer = response.getWriter();
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
writer.write("{\"id\":\"123\"}");
}
-
3、返回字符串
- 如果方法返回String,有3种情况:逻辑视图名、redirect重定向、forward转发
//逻辑视图名
@RequestMapping(value={"/index","/index2"})
public String index(){
return "itemslist";
}
//重定向
@RequestMapping("/update")
public String update() throws ServletException, IOException{
return "redirect:queryItem.action";
}
//转发
@RequestMapping("/updateSubmit")
public String updateSubmit() throws ServletException, IOException{
return "forward:editItem.action";
}
11、springmvc如何处理JSON数据交互?
-
1、使用到的注解
-
@RequestBody:将json、xml 等内容 转换 成Java对象。
-
@ResponseBody:将Java对象 转换 成 json、xml等内容。
-
-
2)、前台代码
$.ajax({
type:"post",
url:"${pageContext.request.contextPath }/item/jsontest.action",
data:'{"id":1,"name":"电冰箱","price":1999.0}',
contentType:"application/json;charset=utf-8",
success:function(data){
alert(data.id +":" +data.name);
}
});
- 3、后台代码
@RequestMapping("/jsontest")
@ResponseBody
public Items jsonTest(@RequestBody Items items) { return items; }
- 4、添加依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.7</version>
</dependency>
12、如何实现文件上传?
- 1、添加依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
- 2、配置多媒体解析器
@Configuration
@ComponentScan(basePackages = "com.czxy.controller")
@EnableWebMvc
public class MVCConfig {
@Bean
public CommonsMultipartResolver multipartResolver(){
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
// 设置所有的上传文件的总大小 10M
multipartResolver.setMaxInMemorySize(10*1024*1024);
// 设置单个文件上传的大小 4M
multipartResolver.setMaxUploadSize(4*1024*1024);
multipartResolver.setDefaultEncoding("utf-8");
return multipartResolver;
}
}
- 3、前台页面
<form id="itemForm" action="${pageContext.request.contextPath }/user/upload.action" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="name"/> <br/>
价格:<input type="text" name="price"/> <br/>
图片:<input type="file" name="picFile"/> <br/>
<input type="submit" value="提交" />
</form>
- 4、后台代码
@RequestMapping("upload")
public String upload(String name,Double price,
@RequestParam(required=false,value="picFile") MultipartFile picFile) throws Exception{
System.out.println("姓名:" + name);
System.out.println("价格:" + price);
String originalFileName = picFile.getOriginalFilename();
System.out.println("上传文件名:" + originalFileName);
//保存文件到指定的位置
File file = new File("D:\\temp", originalFileName);
picFile.transferTo(file);
return "itemslist";
}
13、拦截器如何实现?
-
作用:Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
-
1、自定义拦截器需实现HandlerInterceptor接口
@Component
public class MyInterceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor1拦截器的preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor1拦截器的postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor1拦截器的afterCompletion");
}
}
- 2、注册拦截器
@Configuration
@ComponentScan("com.czxy")
public class SpringMvcConfig extends WebMvcConfigurationSupport {
@Autowired
private MyInterceptor myInterceptor;
//注册连接器
@Override
protected void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptorRegistration = registry.addInterceptor(myInterceptor);
interceptorRegistration.addPathPatterns("/**");
}
}
14、POM附录
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--json转换-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.7</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>9001</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
15、Ajax附录
$.ajax({
type: "POST",
url: "test02",
data: JSON.stringify({username:"zhangsan",password:123}),
contentType:"application/json;charset=utf-8",
success: function(msg){
alert( msg.username );
}
});
16、统一异常处理
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(Exception.class)
@ResponseBody
public String handException(Exception e){
return e.getMessage();
}
}