标签:spel java footer 简化 coding 依赖 exec work 需要
Spring MVC
编程基础
2.2.1. 创建Maven WEB 项目并添加Spring MVC 依赖
2.2.2. 添加Spring MVC配置文件并进行基本配置
9.3. @Value与@PropertySource注解应用
企业级应用中的软件的分层的基本架构
<![if !vml]><![endif]>
说明:分层架构的本质是分而治之,已达到分解问题复杂性的目的,从而更好的进行设计与实现。Ss
基于servlet,jsp,javabean技术实现的MVC架构,具体架构图如下:
<![if !vml]><![endif]>
Spring MVC是MVC架构模式的一种完美实现,它简化了Java WEB 中基于MVC架构的编程过程,是Spring中的WEB应用模块。
Spring MVC 底层核心架构图及工作流程(先了解,写完项目案例再重点强化)
<![if !vml]><![endif]>
Spring MVC 中的核心组件:
<![if !supportLists]>1) <![endif]>DispatcherServlet(前端控制器, 处理请求的入口)
<![if !supportLists]>2) <![endif]>HandlerMapping(映射器对象, 用于管理url与对应controller的映射关系)
<![if !supportLists]>3) <![endif]>Interceptors(拦截器,实现请求响应的共性处理)
<![if !supportLists]>4) <![endif]>Controller (后端控制器, 负责处理请求的控制逻辑)
<![if !supportLists]>5) <![endif]>ViewResolver(视图解析器,解析对应的视图关系:前缀+view+后缀)
备注:假如希望了解Spring MVC的详细处理流程可以基于断点调试法进行跟踪。
Step01:创建maven web 项目并解决项目中的错误问题
Step02:添加Spring MVC项目核心依赖
Step03:配置Spring MVC项目核心组件
Step04:创建Spring MVC 后端控制器及页面
Step05:部署及测试spring mvc 项目应用。
Step01:创建maven web项目
<![if !supportLists]>1) <![endif]>项目名 CGB-SPRING-MVC-01
<![if !vml]><![endif]>
<![if !vml]><![endif]>
<![if !supportLists]>2) <![endif]>Web项目打包方式为war方式
<![if !vml]><![endif]>
Step02:配置maven web项目
<![if !supportLists]>1) <![endif]>生成web.xml
<![if !vml]><![endif]>
<![if !supportLists]>2) <![endif]>Web项目的target runtimes为tomcat
<![if !vml]><![endif]>
3)Web 项目的编译版本为JDK1.8
<![if !vml]><![endif]>
Step03: 添加Spring MVC项目依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
</dependencies>
在项目的resources的目录中添加核心配置文件(例如spring-configs.xml)并进行基本配置
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd" >
<!--配置组件扫描 -->
<context:component-scan base-package="com.jt"/>
<!—启用MVC默认配置 (@RequestMapping) -->
<mvc:annotation-driven/>
<!--配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
说明:配置文件的名字可以自己指定。
打开web.xml,配置DispatcherServlet对象
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-configs.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
前端控制器是spring mvc处理请求的入口,是springmvc的核心,这个控制器一般需要在服务器启动时即初始化。
其中
<![if !supportLists]>1) <![endif]>load-on-startup 表示启动时则加载此servlet,数字越小优先级越高.
<![if !supportLists]>2) <![endif]>init-param中的参数名不能变(此名字在DispatcherServlet父类中定义)
编写Spring MVC后端控制器
@Controller
@RequestMapping("/")
publicclass HelloController{
@RequestMapping("doSayHello")
public ModelAndView doSayHello(String msg) {
ModelAndView mv=new ModelAndView("hello");
mv.addObject("message", "helloworld");
returnmv;
}
}
其中:
1)通过@RequestMapping注解定义url到controller具体方法的映射,这个映射信息会被存储,一般是存储到一个HandlerMapping对象中.
2)ModelAndView对象为一个模型与视图对象,内置一个map对象,主要用于封装业务数据和视图名。
3)ModelAndView构造方法中传递的为视图名,addObject方法可以以key/value形式存储数据。
4)ModelAndView对象返回时会被spring mvc自动存储到请求作用域,在对应的视图页面可以直接从此作用域获取对应的值。
在项目的WEB-INF/pages文件夹下创建hello.jsp文件,然后设置其内容,例如
?
<body>
<h1>${message}</h1>
</body>
?
说明:WEB-INF目录下的资源不能允许通过浏览器地址栏直接访问。
将项目部署到tomcat,然后启动运行,在地址栏输入具体url访问对应controller对象。
问题分析:
<![if !supportLists]>1)<![endif]>tomcat启动时出现ClassNotFoundException,而这个class又不是我们自己的类,此时要重新maven update,重新发布(右键tomcat 重新publish),多次尝试还是不可以,此时重启eclipse。
<![if !supportLists]>2)<![endif]>404异常,一般表示服务端资源没找到,首先检测访问路径是否正确,然后还可以在项目的部署目录中去查找对应的资源,必须确保资源是存在的,假如资源不存在,说明代码没有正常编译。(很常见)
<![if !supportLists]>3)<![endif]>如何解决这种项目不编译的问题?
step01) 停止tomcat将tomcat下的项目移除,并clean你的tomcat服务器(两个clean)
step03) 对项目进行maven clean操作(清除原先编译结构,然后重新编译)
step04) 再次对项目进行clean操作(菜单栏中的project clean)
step05) 重新部署项目,启动tomcat运行
step06) 假如经历了以上几个步骤,还没解决此问题,重启eclipse再试
说明:假如你的eclipse经常出现类似问题,换jdk。
<![if !supportLists]>4)<![endif]>运行项目时尽量不要右键运行选在run as /run on server
项目的请求处理流程结构及过程解析:
<![if !vml]><![endif]>
Step01:客户端向服务服务端发请求
Step02:服务端对请求信息进行过滤(Filter)
Step03:请求到达前端控制DispatcherServlet
Step04:前端控制器基于url在HandlerMapping中的映射找请求执行链
Step05:执行执行链中的拦截器(Interceptor)方法
Step06:执行执行链中的控制器(Controller)方法
Step07:对象控制层返回的视图进行解析
Step08:向客户端返回一个响应结果。
实际项目中我们要借助@RequestMapping注解定义映射路径。其注解应用位置
<![if !supportLists]>ü <![endif]>类定义处: 提供初步的请求映射信息。
<![if !supportLists]>ü <![endif]>方法定义处: 提供进一步的细分映射信息
@RequestMapping(value={"/doSayHello", "/user/doSayWelcome"}):
多个URL路径可以映射到同一个处理器的功能处理方法。
REST即表述性状态传递(英文:Representational State Transfer,简称REST),是一种软件架构编码风格,是基于网络应用进行设计和开发的编码方式。可以降低开发的复杂度,提高程序的可伸缩性。例如:
@RequestMapping("/msg/{xxx}")
请求的URL可以是“/msg/hello”或“/msg/welcome”
@RequestMapping("/msg/{id}/create"):
请求的URL可以是“/users/1/create”。
@RequestMapping("/msg/{mId}/topics/{tId}")
这样也是可以的,请求的URL可以是“/users/10/topics/12”。
说明:通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。
http://localhost:8080/项目名/doUpdate/1.do
项目中Controller层对象的每个方法默认可以处理任意方式的请求,假如要指定控制层方法只能处理GET或只能处理POST请求,那该如何实现呢?
借助@RequestMapping注解中的method属性指定具体的请求处理方式,例如
@RequestMapping(value=”doSaveObj”,
method=RequestMethod.POST)
public String doSaveObject(Object obj){?.}
知识点扩展:
1)@GetMapping 注解应用(定义的映射只能处理get请求)
2)@PostMapping 注解应用(定义的映射只能处理post请求)
项目中还可在控制层方法上借助@RequestMapping注解中的method属性指定使用哪几种方式处理请求。
@RequestMapping(value=”doSaveObj”,
method={RequestMethod.POST,
RequestMethod.GET})
public String doSaveObject(Object obj){?.}
提示:一般浏览器只支持GET或POST方式。
请求映射方法中可以直接使用ServletAPI中的对象获取参数数据,例如
HttpServletRequest,HttpSession对象等,例如:
@RequestMapping(value="withRequest",method=RequestMethod.GET)
@ResponseBody
public String withRequest(HttpServletRequest request){
System.out.println(request.getRequestURI());
return "Obtainer ‘foo‘ query parameter value
‘"+request.getParameter("gid")+"‘";
}
提示:@ResponseBody注解作用:该注解作用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,使用情况:返回的数据不是Html标签的页面,而是其他数据格式的数据时,(如Json、xml,普通文本等)使用;
SpringMVC请求一个控制层资源时,可以在对应方法中直接使用参数变量接收参数数据,但参数变量的类型建议为对象类型。
使用String类型变量接受请求参数的值:
@RequestMapping(value="withStringParam",method=RequestMethod.GET)
@ResponseBody
public String withStringParam(@RequestParam String foo) {
return "Obtained ‘foo‘ query parameter value ‘" + foo + "‘";
}
提示:@RequestParam注解用于接收请求参数中名字为foo的参数值,假如请求参数名与方法中的参数名一致,@RequestParam注解可以省略。假如不一致则可以使用@RequestParam注解定义新的参数名直接接收页面数据,然后传递给方法名,还有就是请求参数中包含特殊字符时,需要借助@RequestParam注解对参数进行声明。例如
@RequestMapping(value="withStringParam", method=RequestMethod.GET)
@ResponseBody
public String withStringParam(
@RequestParam(value="param-01",required=false) String foo) {
return "Obtained ‘foo‘ query parameter value ‘" + foo + "‘";
}
提示:required=false表示,参数可以不存在,假如为true(默认),参数不存在时会抛出异常(400异常)。
使用Date类型变量接受请求日期参数的值:
@RequestMapping(value="withDateParam")
@ResponseBody
public String withDateParam(Date birthday) {
return "Obtained date parameter value ‘" + birthday + "‘";
}
Spring MVC 默认支持yyyy/MM/dd格式日期转换,假如日期格式不匹配会报400异常
使用Integer类型的可变参数或数组接收请求数据
@RequestMapping(value="withVarParam")
@ResponseBody
public String withVarParam(Integer? ids) {
return "Obtained ids parameter value ‘" + ids + "‘";
}
当请求中多个参数时可以通过在方法中定义多个参数接收参数数据,也可以利用一个javabean对象接收多个参数数据以简化多个参数变量的定义。
@RequestMapping(value="withParamGroup",method=RequestMethod.GET)
@ResponseBody
public String withParamGroup(SysLog entity) {
return "Obtained javabean parameter group " + entity;
}
提示:当使用javabean接收请求参数数据时,bean中需要有与参数名对应的set方法。
说明:通过map接收页面参数时,需要使用@RequestParam注解声明
@RequestMapping("doMap02")
public String withParamGroup (
@RequestParam Map<String,Object> map) {
return "Obtained map parameter group " + map;
}
提示:此时的map不能再作为响应数据的封装对象
SpringMVC请求资源路径的URL可以通过{XXX}形式指定动态的URL,动态URL中的这个可变参数的值可以直接注入到方法对应的参数中。
@RequestMapping(value="path/{var}",method=RequestMethod.GET)
@ResponseBody
public String withPathVariable(@PathVariable String var) {
return "Obtained ‘var‘ path variable value ‘" + var + "‘";
}
通过@PathVariable注解指定参数变量var获取请求url中{var}数据
当服务端要获取客户端请求头中数据信息时,可通过@RequestHeader即可将请求头中
的属性值绑定到处理方法的入参中,例如获取请求中Accept属性的值,然后传入到对应方法的参数中。
@RequestMapping(value="header", method=RequestMethod.GET)
@ResponseBody
public String withHeader(@RequestHeader String Accept) {
return "Obtained ‘Accept‘ header ‘" + Accept + "‘";
}
假如希望在此方法中直接从cookie取值,可以定义参数时使用@CookieValue对参数进行修饰,参数名一般要与cookie对象中的key相同
@RequestMapping(value="withCookie")
@ResponseBody
public String withCooke(
@CookieValue String JSESSIONID) {
return "Obtained COOKIE Value ‘" + JSESSIONID + "‘";
}
提示:方法中的参数名需要与请求头参数中某个参数名相同,具体请求头相关信息可以在浏览器控制台查看。
当应用中要获取请求中所有数据时可以在请求方法中定义一个HttpEntity<String>参数,通过此参数获取请求头及请求体中数据,例如
@RequestMapping(value="entity", method=RequestMethod.POST)
public @ResponseBody String withEntity(
HttpEntity<String> entity) {
return "Posted request body " + entity.getBody() + "
headers = " + entity.getHeaders();
}
如上写法:了解
将请求数据直接封装到Request 对象
@RequestMapping("doResponse01")
public String doResponse01(HttpServletRequest request) {
request.setAttribute("data", "hello..");
return"response";
}
在response.jsp页面可以直接借助${data}方式获取数据。
当方法中直接返回一个页面时,默认执行的是请求转发,假如需要实现重定向,
可以在返回的地址后添加redirect,例如
return "redirect:responseUI.do"; 其中responseUI.do对应一个请求url.
@RequestMapping("doResponse02")
public String doResponse02(HttpServletRequest request) {
request.setAttribute("data", "hello..");
return"redirect:responseUI.do";
}
在如上方法中可以重定向到一个responseUI对应的新的URL。
@RequestMapping("responseUI")
public String responseUI() {
return"response";
}
在新的请求中不能直接获取上一个请求作用域的数据。
回顾请求转发与重定向:
1)请求转发(forward)
<![if !vml]><![endif]>
<![if !supportLists]>3) <![endif]>重定向(redirect)
<![if !vml]><![endif]>
课堂练习:
例如: 将响应数据封装1到Session,然后在客户端获取作用域数据
@RequestMapping("doResponse03")
public String doResponse03(HttpSession session) {
session.setAttribute("data", "map..");
return"response";
}
在对服务端响应数据进行封装时,可以直接在方法参数中定义一个ModelAndView类型的参数,借助ModelAndView对象封装响应数据.
@RequestMapping("doModelAndView")
public ModelAndView doModelAndView(ModelAndView mv) {
//ModelAndView mv=new ModelAndView();
mv.addObject("data", "model and view");
mv.setViewName("response");//view
returnmv;
}
提示:ModelAndView 对象由Spring创建,并可以将数据存储到ModelAndView对象的ModalMap类型的属性中(可参考源代码).
将响应数据直接封装为model中。
@RequestMapping("doModel")
public String doModel(Model model) {
model.addAttribute("data", "modal");
return"response";
}
当我们返回具体view时,系统底层会自动将model对象存储到request作用域。
将响应数据封装到Map中(我建议假如使用map对数据进行封装,可直接采用model对象)。
@RequestMapping("doMap01")
public String doMap01(Map<String,Object> map) {
map.put("data", "map..");
return"response";
}
JSON(JavaScript Object Notation):一种轻量级数据交换格式,通常作为客户端与服务端进行数据交互的一种标准。
企业级Java项目数据传输方式:
<![if !vml]><![endif]>
reponse.getWriter().write(jsonStr);
客户端访问服务端时,服务器从数据库取出数据进行封装,然后再将对象转换为json串,通过网络传输到客户端。
spring 中默认支持jackson应用的,但使用时需要添加jackson依赖,例如
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
创建Controller中例如ResponseController,然后在类中添加对应方法。例如
将Map对象内容转换为字符串(spring底层会直接访问jackson api将对象转换为字符串)
@RequestMapping("doMap")
@ResponseBody
public Map<String,Object> doMap(){
Map<String,Object> map=
new HashMap<>();
map.put("id", 100);
map.put("name", "AAA");
returnmap;
}
将JavaBean对象转换为JSON串
@RequestMapping("doUser")
@ResponseBody
public SysLog doLog(){
SysLog log=new SysLog ();
log.setId(100);
log.setUsername("CCC");
log.setIP("192.168.1.12");
returnlog;
}
将Java List集合转换为JSON串。
@RequestMapping("doList")
@ResponseBody
public List<SysLog> doList(){
List<SysLog> list=new ArrayList<>();
SysLog log=new SysLog ();
log.setId(100);
log.setUsername("CCC");
log.setIP("192.168.1.12");
list.add(log);
log=new SysLog ();
log.setId(100);
log.setUsername("CCC");
log.setIP("192.168.1.12");
list.add(log);
returnlist;
}
备注:将来controller中数据来自服务端数据。
<![if !supportLists]>1. <![endif]>Spring MVC 组件的核心架构及基本组件?
<![if !supportLists]>2. <![endif]>Spring MVC 请求响应流程分析?
<![if !supportLists]>1. <![endif]>总结课堂知识点 <![if !supportLists]>2. <![endif]>熟练掌握spring MVC项目的创建及基本配置 <![if !supportLists]>3. <![endif]>强化理解spring MVC中请求和响应数据的处理
思考:如何使用Spring 集成fastjson库(阿里巴巴的高性能JSON库)
|
spring 中默认不支持fastjson api直接将java对象转换为json串,假如需要使用fastjson实现对象的转换,现阶段我们需要手动进行转换。
Step01:项目中添加fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.38</version>
</dependency>
Step02: 配置fastjson为默认json转换器
<mvc:annotation-driven>
<!--设置fastjson的转换器对象 -->
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8</value>
<value>application/json;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Step03: 应用fastjson,控制层的方法可以直接返回javabean或对应的map对象
@RequestMapping("doRespJSON01")
@ResponseBody
public Map<String,Object> doRespJSON01(){
Map<String,Object> map=
new HashMap<String, Object>();
map.put("id", 100);
map.put("name","tmooc");
returnmap;
}
访问对象方法此时方法的返回对象会由FastJsonHttpMessageConverter对象转换为JSON格式的字符串.
标签:spel java footer 简化 coding 依赖 exec work 需要
原文地址:https://www.cnblogs.com/wood-life/p/10291801.html