();
74 |
75 | //向list中填充静态数据
76 | Items items_1 = new Items();
77 | items_1.setName("联想笔记本");
78 | items_1.setPrice(6000f);
79 | items_1.setDetail("ThinkPad T430 c3 联想笔记本电脑!");
80 |
81 | Items items_2 = new Items();
82 | items_2.setName("苹果手机");
83 | items_2.setPrice(5000f);
84 | items_2.setDetail("iphone6苹果手机!");
85 |
86 | itemsList.add(items_1);
87 | itemsList.add(items_2);
88 |
89 | //返回ModelAndView
90 | ModelAndView modelAndView = new ModelAndView();
91 | //相当于request的setAttribute方法,在jsp页面中通过itemsList取数据
92 | modelAndView.addObject("itemsList",itemsList);
93 |
94 | //指定视图
95 | modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
96 | return modelAndView;
97 | }
98 | }
99 | ```
100 |
101 | ## 在spring容器中加载Handler
102 |
103 | ```xml
104 |
107 |
108 |
111 |
112 | ```
113 |
114 |
115 |
116 | ## 参考资料
117 |
118 | >* [SpringMVC框架】注解的处理器映射器和适配器配置](http://blog.csdn.net/acmman/article/details/46980427)
--------------------------------------------------------------------------------
/springmvc/04 前端控制器.md:
--------------------------------------------------------------------------------
1 | # 04 前端控制器
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 |
10 |
11 | ---
12 |
13 |
14 | 通过前端控制器源码分析springmvc执行过程
15 |
16 | 1. 前端控制器接收请求
17 |
18 | 调用`doDispatch`方法
19 |
20 | ```java
21 | protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
22 | HttpServletRequest processedRequest = request;
23 | HandlerExecutionChain mappedHandler = null;
24 | boolean multipartRequestParsed = false;
25 |
26 | 。。。。。
27 | }
28 | ```
29 |
30 | 2. 前端控制器调用`HandlerMapping`(处理器映射器)根据url查找Handler
31 |
32 |
33 | ```java
34 | // Determine handler for the current request.
35 | mappedHandler = getHandler(processedRequest);
36 | ```
37 |
38 | ```java
39 | /**
40 | * Return the HandlerExecutionChain for this request.
41 | * Tries all handler mappings in order.
42 | * @param request current HTTP request
43 | * @return the HandlerExecutionChain, or {@code null} if no handler could be found
44 | */
45 | protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
46 | for (HandlerMapping hm : this.handlerMappings) {
47 | if (logger.isTraceEnabled()) {
48 | logger.trace(
49 | "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
50 | }
51 | HandlerExecutionChain handler = hm.getHandler(request);
52 | if (handler != null) {
53 | return handler;
54 | }
55 | }
56 | return null;
57 | }
58 | ```
59 |
60 | 3. 调用处理器适配器执行Handler,得到执行的结果`ModelAndView mv`
61 |
62 | 在`doDispatch`方法中
63 |
64 | ```java
65 | // Actually invoke the handler.
66 | mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
67 | ```
68 |
69 | 4. 视图渲染,将model数据填充到request域
70 |
71 | `doDispatch`->`processDispatchResult`->`render`
72 |
73 | 在`render`方法中,视图解析得到view
74 |
75 | ```java
76 | // We need to resolve the view name.
77 | view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
78 |
79 | ```
80 |
81 | 调用view的渲染方法,将model数据填充到request域
82 |
83 | 在`render`方法中,调用`View`接口的`render`方法
84 |
85 | ```java
86 | view.render(mv.getModelInternal(), request, response);
87 | ```
88 |
89 |
90 | 程序我也没细读,感觉分析比较浅,很多还没弄懂,等我系统阅读源码后会整理一篇好点的。
91 |
--------------------------------------------------------------------------------
/springmvc/05 入门程序小结.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(5)-入门程序小结
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [入门程序配置小结](#入门程序配置小结)
10 | - [非注解的完整的配置文件](#非注解的完整的配置文件)
11 | - [注解的完整配置文件](#注解的完整配置文件)
12 |
13 |
14 |
15 | ---
16 |
17 |
18 | 通过入门程序理解springmvc前端控制器、处理器映射器、处理器适配器、视图解析器用法。并附上入门程序的非注解的完整的配置文件,注解的完整配置文件。
19 |
20 | ## 入门程序配置小结
21 |
22 | 前端控制器配置:
23 |
24 | - 第一种:`*.action`,访问以`.action`结尾 由`DispatcherServlet`进行解析
25 | - 第二种:`/`,所以访问的地址都由`DispatcherServlet`进行解析,对于静态文件的解析需要配置不让`DispatcherServlet`进行解析,使用此种方式可以实现RESTful风格的url
26 |
27 | 处理器映射器:
28 |
29 | - 非注解处理器映射器(了解)
30 | - 注解的处理器映射器(掌握)
31 | - 对标记 `@Controller` 类中标识有 `@RequestMapping` 的方法进行映射。在 `@RequestMapping` 里边定义映射的 url 。使用注解的映射器不用在 xml 中配置 url 和 Handler 的映射关系。
32 |
33 | 处理器适配器:
34 |
35 | - 非注解处理器适配器(了解)
36 | - 注解的处理器适配器(掌握)
37 | - 注解处理器适配器和注解的处理器映射器是**配对使用**。理解为不能使用非注解映射器进行映射。
38 |
39 |
40 |
41 | ```xml
42 |
43 | ```
44 |
45 | 可以代替下边的配置:
46 |
47 | ```xml
48 |
49 |
50 |
51 |
52 | ```
53 |
54 |
55 |
56 | ## 非注解的完整的配置文件
57 |
58 | `src/main/resources/springmvc.xml`
59 |
60 | ```xml
61 |
68 |
69 |
70 |
71 |
72 |
75 |
76 |
77 |
80 |
81 |
82 |
85 |
86 |
87 |
88 | ```
89 |
90 |
91 |
92 | ## 注解的完整配置文件
93 |
94 | ```xml
95 |
102 |
103 |
106 |
107 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
124 |
125 |
126 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | ```
138 |
139 |
--------------------------------------------------------------------------------
/springmvc/06 springmvc整合mybatis-mvn构建.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(6)-springmvc整合mybatis(IDEA中通过maven构建)
2 |
3 | 标签: springmvc mybatis
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [整合思路](#整合思路)
10 | - [工程结构](#工程结构)
11 | - [添加依赖](#添加依赖)
12 | - [建包](#建包)
13 |
14 |
15 |
16 | ---
17 |
18 |
19 | 本文主要展示如何在intellij IDEA中通过maven构建springmvc+mybatis框架的开发环境。
20 |
21 |
22 |
23 | 需求:使用springmvc和mybatis完成商品列表查询
24 |
25 | ## 整合思路
26 |
27 | 
28 |
29 |
30 | - 第一步:整合dao层
31 | - mybatis和spring整合,通过spring管理mapper接口。
32 | - 使用mapper的扫描器自动扫描mapper接口在spring中进行注册。
33 |
34 | - 第二步:整合service层
35 | - 通过spring管理service接口。
36 | - 使用配置方式将service接口配置在spring配置文件中。
37 | - 实现事务控制。
38 |
39 | - 第三步:整合springmvc
40 | - 由于springmvc是spring的模块,不需要整合。
41 |
42 |
43 |
44 | ## 工程结构
45 |
46 | 不同于[《mybatis学习笔记(17)-spring和mybatis整合》](http://blog.csdn.net/h3243212/article/details/50778934)中的示例demo,**本文的整合采用maven构建**。
47 |
48 | 如何创建使用maven构建的web应用可以参考前面的一篇[《springmvc学习笔记(1)-框架原理和入门配置》](http://blog.csdn.net/h3243212/article/details/50828141#环境搭建)
49 |
50 | `new->project->maven`,建一个裸的maven工程,手动建webapp的目录
51 |
52 | 在`src/main`下新建文件夹`webapp`
53 |
54 | ### 添加依赖
55 |
56 | pom.xml文件
57 |
58 | ```xml
59 |
60 |
63 | 4.0.0
64 |
65 | com.iot.learnssm
66 | learnssm-firstssm
67 | 1.0-SNAPSHOT
68 | war
69 |
70 |
71 | UTF-8
72 |
73 | 4.2.4.RELEASE
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | org.springframework
82 | spring-webmvc
83 | ${spring.version}
84 |
85 |
86 |
87 | org.springframework
88 | spring-core
89 | ${spring.version}
90 |
91 |
92 |
93 | org.springframework
94 | spring-orm
95 | ${spring.version}
96 |
97 |
98 |
99 | org.springframework
100 | spring-aspects
101 | ${spring.version}
102 |
103 |
104 |
105 | org.springframework
106 | spring-test
107 | ${spring.version}
108 |
109 |
110 |
111 | org.springframework
112 | spring-jdbc
113 | ${spring.version}
114 |
115 |
116 |
117 |
118 | mysql
119 | mysql-connector-java
120 | 5.1.38
121 |
122 |
123 | org.mybatis
124 | mybatis
125 | 3.3.1
126 |
127 |
128 | org.mybatis
129 | mybatis-spring
130 | 1.2.4
131 |
132 |
133 | log4j
134 | log4j
135 | 1.2.17
136 |
137 |
138 |
139 | org.slf4j
140 | slf4j-api
141 | 1.7.18
142 |
143 |
144 |
145 | commons-dbcp
146 | commons-dbcp
147 | 1.4
148 |
149 |
150 |
151 |
152 | javax.servlet
153 | jstl
154 | 1.2
155 |
156 |
157 | taglibs
158 | standard
159 | 1.1.2
160 |
161 |
162 |
163 |
164 | ```
165 |
166 | 这里添加的依赖可能有多的,但总比少包好,我开始就是引少了依赖(springframework的依赖只引用了spring-mvc,连spring-core都没引),导致报错,以后会出一篇博客专门讲这个系列笔记中debug相关问题。
167 |
168 |
169 | ### 建包
170 |
171 | 在java目录下建各个package,按照maven的命名习惯:
172 |
173 | `com.公司名.项目名.模块名`
174 |
175 | 这里我的包为:
176 |
177 | `com.iot.learnssm.firstssm`
178 |
179 | 包含几个子包:
180 |
181 | - controller
182 | - mapper
183 | - po
184 | - service
185 | - impl
186 |
187 |
188 | 后面几篇笔记会依次记录mapper,service,controller各个部分的整合
189 |
190 | ----
191 |
192 |
193 |
194 |
195 |
196 |
--------------------------------------------------------------------------------
/springmvc/07 springmvc整合mybatis之mapper.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(7)-springmvc整合mybatis之mapper
2 |
3 | 标签: springmvc mybatis
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [整合dao](#整合dao)
10 | - [Global logging configuration](#global-logging-configuration)
11 | - [Console output...](#console-output)
12 | - [sqlMapConfig.xml](#sqlmapconfigxml)
13 | - [applicationContext-dao.xml](#applicationcontext-daoxml)
14 | - [逆向工程生成po类及mapper(单表增删改查)](#逆向工程生成po类及mapper单表增删改查)
15 | - [手动定义商品查询mapper](#手动定义商品查询mapper)
16 |
17 |
18 |
19 | ---
20 |
21 | 本文记录springmvc整合dao的配置
22 |
23 | ## 整合dao
24 |
25 | 首先在resource文件夹下添加两个文件:数据库配置文件和日志配置文件
26 |
27 | - 数据库配置文件db.properties
28 |
29 | ```
30 | jdbc.driver=com.mysql.jdbc.Driver
31 | jdbc.url=jdbc:mysql://120.25.162.238:3306/mybatis001?characterEncoding=utf-8
32 | jdbc.username=root
33 | jdbc.password=123
34 | ```
35 |
36 | - 日志配置文件log4j.properties
37 |
38 | ```
39 | # Global logging configuration
40 | log4j.rootLogger=DEBUG, stdout
41 | # Console output...
42 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
43 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
44 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
45 | ```
46 |
47 | ### sqlMapConfig.xml
48 |
49 | mybatis自己的配置文件
50 |
51 | 在resources目录下新建mybatis文件夹,并新建sqlMapConfig.xml文件
52 |
53 | ```xml
54 |
55 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
72 |
73 |
76 |
77 | ```
78 |
79 |
80 | ### applicationContext-dao.xml
81 |
82 | 在resources目录下新建spring文件夹,并新建applicationContext-dao.xml文件
83 |
84 | 配置:
85 |
86 | - 数据源
87 | - SqlSessionFactory
88 | - mapper扫描器
89 |
90 |
91 |
92 | ```xml
93 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
131 |
132 |
133 |
134 |
135 | ```
136 |
137 |
138 | ### 逆向工程生成po类及mapper(单表增删改查)
139 |
140 | 方法参见[《mybatis学习笔记(18)-mybatis逆向工程》](http://blog.csdn.net/h3243212/article/details/50778937)
141 |
142 |
143 | ### 手动定义商品查询mapper
144 |
145 | 针对综合查询mapper,一般情况会有关联查询,建议自定义mapper
146 |
147 | - ItemsMapperCustom.xml
148 |
149 | ```xml
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 | items.name LIKE '%${itemsCustom.name}%'
161 |
162 |
163 |
164 |
165 |
166 |
167 |
170 |
177 |
178 |
179 | ```
180 |
181 | - ItemsMapperCustom.java
182 |
183 | ```java
184 | public interface ItemsMapperCustom {
185 | //商品查询列表
186 | List findItemsList(ItemsQueryVo itemsQueryVo)throws Exception;
187 | }
188 | ```
189 |
190 | - po类`ItemsCustom`
191 |
192 | ```java
193 | package com.iot.learnssm.firstssm.po;
194 |
195 | /**
196 | * Created by Brian on 2016/3/2.
197 | * 商品信息的扩展类
198 | */
199 | public class ItemsCustom extends Items{
200 | //添加商品信息的扩展属性
201 | }
202 | ```
203 |
204 | - 输入pojo的包装类
205 |
206 | ```java
207 | package com.iot.learnssm.firstssm.po;
208 |
209 | /**
210 | * Created by Brian on 2016/3/2.
211 | */
212 | public class ItemsQueryVo {
213 |
214 | //商品信息
215 | private Items items;
216 |
217 | //为了系统 可扩展性,对原始生成的po进行扩展
218 | private ItemsCustom itemsCustom;
219 |
220 | public Items getItems() {
221 | return items;
222 | }
223 |
224 | public void setItems(Items items) {
225 | this.items = items;
226 | }
227 |
228 | public ItemsCustom getItemsCustom() {
229 | return itemsCustom;
230 | }
231 |
232 | public void setItemsCustom(ItemsCustom itemsCustom) {
233 | this.itemsCustom = itemsCustom;
234 | }
235 | }
236 | ```
237 |
238 |
239 | 整合好dao后的工程目录如图
240 |
241 |
--------------------------------------------------------------------------------
/springmvc/08 springmvc整合mybatis之service.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(8)-springmvc整合mybatis之service
2 |
3 | 标签: springmvc mybatis
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [定义service接口](#定义service接口)
10 | - [在spring容器配置service](#在spring容器配置service)
11 | - [事务控制](#事务控制)
12 |
13 |
14 |
15 | ---
16 |
17 |
18 | 本文记录如何整合service,包括定义spring接口,在spring容器配置service以及事务控制。让spring管理service接口。
19 |
20 |
21 | ## 定义service接口
22 |
23 | ```java
24 | public interface ItemsService {
25 | //商品查询列表
26 | List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception;
27 |
28 | }
29 | ```
30 |
31 | ```java
32 | public class ItemsServiceImpl implements ItemsService {
33 |
34 | @Autowired
35 | private ItemsMapperCustom itemsMapperCustom;
36 |
37 | public List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception {
38 | return itemsMapperCustom.findItemsList(itemsQueryVo);
39 | }
40 | }
41 | ```
42 |
43 | ## 在spring容器配置service
44 |
45 |
46 | 在`resources/spring`下创建applicationContext-service.xml,文件中配置service。
47 |
48 | ```xml
49 |
52 |
53 |
54 |
55 |
56 |
57 | ```
58 |
59 | ## 事务控制
60 |
61 | 在`resources/spring`下创建applicationContext-transaction.xml,在applicationContext-transaction.xml中使用spring声明式事务控制方法。
62 |
63 | ```xml
64 |
65 |
72 |
73 |
74 |
77 |
78 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | ```
103 |
--------------------------------------------------------------------------------
/springmvc/09 springmvc整合mybatis之controller.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(9)-springmvc整合mybatis之controller
2 |
3 | 标签: springmvc mybatis
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [springmvc.xml](#springmvcxml)
10 | - [配置web.xml](#配置webxml)
11 | - [编写Controller(就是Handler)](#编写controller就是handler)
12 | - [编写jsp](#编写jsp)
13 |
14 |
15 |
16 | ---
17 |
18 |
19 | 本文介绍如何配置springmvc配置文件和web.xml,以及如何编写controller,jsp
20 |
21 |
22 | ## springmvc.xml
23 |
24 | 在`resources/spring`文件下下创建springmvc.xml文件,配置处理器映射器、适配器、视图解析器。
25 |
26 | ```xml
27 |
34 |
35 |
38 |
41 |
42 |
43 |
44 |
49 |
50 |
51 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | ```
63 |
64 | ## 配置web.xml
65 |
66 |
67 | 参考入门程序,web.xml
68 |
69 | ```xml
70 |
71 |
74 | firstssm
75 |
76 |
77 |
78 | contextConfigLocation
79 | WEB-INF/classes/spring/applicationContext-*.xml
80 |
81 |
82 |
83 | org.springframework.web.context.ContextLoaderListener
84 |
85 |
86 |
87 |
88 |
89 | springmvc
90 | org.springframework.web.servlet.DispatcherServlet
91 |
94 |
95 | contextConfigLocation
96 | classpath:spring/springmvc.xml
97 |
98 |
99 |
100 |
101 | springmvc
102 |
109 | *.action
110 |
111 |
112 |
113 |
114 | index.html
115 | index.htm
116 | index.jsp
117 | default.html
118 | default.htm
119 | default.jsp
120 |
121 |
122 | ```
123 |
124 | 这个文件有两个作用:
125 |
126 | - 配置前端控制器(`DispatcherServlet`)
127 | - 加载spring容器:添加spring容器监听器,加载spring容器,使用通配符加载`spring/`下的配置文件
128 | - applicationContext-dao.xml
129 | - applicationContext-service.xml
130 | - applicationContext-transaction.xml
131 |
132 |
133 |
134 | ## 编写Controller(就是Handler)
135 |
136 |
137 | ```java
138 | package com.iot.learnssm.firstssm.controller;
139 |
140 |
141 | import com.iot.learnssm.firstssm.po.Items;
142 | import com.iot.learnssm.firstssm.po.ItemsCustom;
143 | import com.iot.learnssm.firstssm.service.ItemsService;
144 | import org.springframework.beans.factory.annotation.Autowired;
145 | import org.springframework.stereotype.Controller;
146 | import org.springframework.web.bind.annotation.RequestMapping;
147 | import org.springframework.web.servlet.ModelAndView;
148 |
149 | import java.util.ArrayList;
150 | import java.util.List;
151 |
152 | /**
153 | * Created by brian on 2016/3/2.
154 | */
155 |
156 | //使用@Controller来标识它是一个控制器
157 | @Controller
158 | //为了对url进行分类管理 ,可以在这里定义根路径,最终访问url是根路径+子路径
159 | //比如:商品列表:/items/queryItems.action
160 | public class ItemsController {
161 |
162 | @Autowired
163 | private ItemsService itemsService;
164 |
165 | //商品查询列表
166 | @RequestMapping("/queryItems")
167 | //实现 对queryItems方法和url进行映射,一个方法对应一个url
168 | //一般建议将url和方法写成一样
169 | public ModelAndView queryItems() throws Exception{
170 | //调用service查找数据库,查询商品列表
171 | List itemsList = itemsService.findItemsList(null);
172 |
173 | //返回ModelAndView
174 | ModelAndView modelAndView = new ModelAndView();
175 | //相当于request的setAttribute方法,在jsp页面中通过itemsList取数据
176 | modelAndView.addObject("itemsList",itemsList);
177 |
178 | //指定视图
179 | //下边的路径,如果在视图解析器中配置jsp的路径前缀和后缀,修改为items/itemsList
180 | //modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
181 | //下边的路径配置就可以不在程序中指定jsp路径的前缀和后缀
182 | modelAndView.setViewName("items/itemsList");
183 |
184 | return modelAndView;
185 | }
186 |
187 |
188 | }
189 | ```
190 |
191 | ## 编写jsp
192 |
193 | 服务器路径为`WEB-INF/jsp/items/itemsList.jsp`
194 |
195 | ```jsp
196 | <%@ page language="java" contentType="text/html; charset=UTF-8"
197 | pageEncoding="UTF-8"%>
198 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
199 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
200 |
201 |
202 |
203 |
204 | 查询商品列表
205 |
206 |
207 |
237 |
238 |
239 |
240 | ```
241 |
242 |
243 |
--------------------------------------------------------------------------------
/springmvc/10 springmvc注解开发之商品修改功能.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(10)-springmvc注解开发之商品修改功能
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [需求](#需求)
10 | - [开发mapper](#开发mapper)
11 | - [开发service](#开发service)
12 | - [开发controller](#开发controller)
13 | - [`@RequestMapping`](#@requestmapping)
14 | - [controller方法的返回值](#controller方法的返回值)
15 |
16 |
17 |
18 | ---
19 |
20 | 本文以商品修改为例,记录springmvc的注解开发,包括mapper,service,controller,@RequestMapping,controller方法的返回值等
21 |
22 | ## 需求
23 |
24 | 操作流程:
25 |
26 | - 1.进入商品查询列表页面
27 | - 2.点击修改,进入商品修改页面,页面中显示了要修改的商品。要修改的商品从数据库查询,根据商品id(主键)查询商品信息
28 | - 3.在商品修改页面,修改商品信息,修改后,点击提交
29 |
30 | ## 开发mapper
31 |
32 | mapper:
33 |
34 | - 根据id查询商品信息
35 | - 根据id更新Items表的数据
36 |
37 | 不用开发了,使用逆向工程生成的代码。
38 |
39 | ## 开发service
40 |
41 | 在`com.iot.learnssm.firstssm.service.ItemsService`中添加两个接口
42 |
43 | ```java
44 | //根据id查询商品信息
45 | /**
46 | *
47 | * Title: findItemsById
48 | * Description:
49 | * @param id 查询商品的id
50 | * @return
51 | * @throws Exception
52 | */
53 | ItemsCustom findItemsById(Integer id) throws Exception;
54 |
55 | //修改商品信息
56 | /**
57 | *
58 | * Title: updateItems
59 | * Description:
60 | * @param id 修改商品的id
61 | * @param itemsCustom 修改的商品信息
62 | * @throws Exception
63 | */
64 | void updateItems(Integer id,ItemsCustom itemsCustom) throws Exception;
65 |
66 | ```
67 |
68 | 在`com.iot.learnssm.firstssm.service.impl.ItemsServiceImpl`中实现接口,增加`itemsMapper`属性
69 |
70 |
71 | ```java
72 | @Autowired
73 | private ItemsMapper itemsMapper;
74 |
75 | public ItemsCustom findItemsById(Integer id) throws Exception {
76 | Items items = itemsMapper.selectByPrimaryKey(id);
77 | //中间对商品信息进行业务处理
78 | //....
79 | //返回ItemsCustom
80 | ItemsCustom itemsCustom = new ItemsCustom();
81 | //将items的属性值拷贝到itemsCustom
82 | BeanUtils.copyProperties(items, itemsCustom);
83 |
84 | return itemsCustom;
85 | }
86 |
87 | public void updateItems(Integer id, ItemsCustom itemsCustom) throws Exception {
88 | //添加业务校验,通常在service接口对关键参数进行校验
89 | //校验 id是否为空,如果为空抛出异常
90 |
91 | //更新商品信息使用updateByPrimaryKeyWithBLOBs根据id更新items表中所有字段,包括 大文本类型字段
92 | //updateByPrimaryKeyWithBLOBs要求必须转入id
93 | itemsCustom.setId(id);
94 | itemsMapper.updateByPrimaryKeyWithBLOBs(itemsCustom);
95 | }
96 | ```
97 |
98 | ## 开发controller
99 |
100 | 方法:
101 |
102 | - 商品信息修改页面显示
103 | - 商品信息修改提交
104 |
105 | ```java
106 | //使用@Controller来标识它是一个控制器
107 | @Controller
108 | //为了对url进行分类管理 ,可以在这里定义根路径,最终访问url是根路径+子路径
109 | //比如:商品列表:/items/queryItems.action
110 | //@RequestMapping("/items")
111 | public class ItemsController {
112 |
113 | @Autowired
114 | private ItemsService itemsService;
115 |
116 | //商品查询列表
117 | @RequestMapping("/queryItems")
118 | //实现 对queryItems方法和url进行映射,一个方法对应一个url
119 | //一般建议将url和方法写成一样
120 | public ModelAndView queryItems() throws Exception{
121 | //调用service查找数据库,查询商品列表
122 | List itemsList = itemsService.findItemsList(null);
123 |
124 | //返回ModelAndView
125 | ModelAndView modelAndView = new ModelAndView();
126 | //相当于request的setAttribute方法,在jsp页面中通过itemsList取数据
127 | modelAndView.addObject("itemsList",itemsList);
128 |
129 | //指定视图
130 | //下边的路径,如果在视图解析器中配置jsp的路径前缀和后缀,修改为items/itemsList
131 | //modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
132 | //下边的路径配置就可以不在程序中指定jsp路径的前缀和后缀
133 | modelAndView.setViewName("items/itemsList");
134 |
135 | return modelAndView;
136 | }
137 |
138 |
139 | //商品信息修改页面显示
140 | @RequestMapping("/editItems")
141 | //限制http请求方法,可以post和get
142 | //@RequestMapping(value="/editItems",method={RequestMethod.POST, RequestMethod.GET})
143 | public ModelAndView editItems()throws Exception {
144 |
145 | //调用service根据商品id查询商品信息
146 | ItemsCustom itemsCustom = itemsService.findItemsById(1);
147 |
148 | // 返回ModelAndView
149 | ModelAndView modelAndView = new ModelAndView();
150 |
151 | //将商品信息放到model
152 | modelAndView.addObject("itemsCustom", itemsCustom);
153 |
154 | //商品修改页面
155 | modelAndView.setViewName("items/editItems");
156 |
157 | return modelAndView;
158 | }
159 |
160 | //商品信息修改提交
161 | @RequestMapping("/editItemsSubmit")
162 | public ModelAndView editItemsSubmit(HttpServletRequest request, Integer id, ItemsCustom itemsCustom)throws Exception {
163 |
164 | //调用service更新商品信息,页面需要将商品信息传到此方法
165 | itemsService.updateItems(id, itemsCustom);
166 |
167 | //返回ModelAndView
168 | ModelAndView modelAndView = new ModelAndView();
169 | //返回一个成功页面
170 | modelAndView.setViewName("success");
171 | return modelAndView;
172 | }
173 |
174 | }
175 |
176 | ```
177 |
178 |
179 |
180 | ## `@RequestMapping`
181 |
182 | - url映射
183 |
184 | 定义controller方法对应的url,进行处理器映射使用。
185 |
186 |
187 | - 窄化请求映射
188 |
189 | ```java
190 | //使用@Controller来标识它是一个控制器
191 | @Controller
192 | //为了对url进行分类管理 ,可以在这里定义根路径,最终访问url是根路径+子路径
193 | //比如:商品列表:/items/queryItems.action
194 | @RequestMapping("/items")
195 | public class ItemsController {
196 | ```
197 |
198 |
199 | - 限制http请求方法
200 |
201 | 出于安全性考虑,对http的链接进行方法限制。
202 |
203 | ```java
204 | //商品信息修改页面显示
205 | //@RequestMapping("/editItems")
206 | //限制http请求方法,可以post和get
207 | @RequestMapping(value="/editItems",method={RequestMethod.POST, RequestMethod.GET})
208 | public ModelAndView editItems()throws Exception {
209 | ```
210 |
211 | 如果限制请求为post方法,进行get请求,即将上面代码的注解改为`@RequestMapping(value="/editItems",method={RequestMethod.POST})`
212 |
213 | 报错,状态码405:
214 |
215 | 
216 |
217 |
218 |
219 |
220 | ## controller方法的返回值
221 |
222 | - 返回`ModelAndView`
223 |
224 | 需要方法结束时,定义ModelAndView,将model和view分别进行设置。
225 |
226 |
227 | - 返回string
228 |
229 | 如果controller方法返回string
230 |
231 | 1.表示返回逻辑视图名。
232 |
233 | 真正视图(jsp路径)=前缀+逻辑视图名+后缀
234 |
235 | ```java
236 | @RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
237 | //@RequestParam里边指定request传入参数名称和形参进行绑定。
238 | //通过required属性指定参数是否必须要传入
239 | //通过defaultValue可以设置默认值,如果id参数没有传入,将默认值和形参绑定。
240 | //public String editItems(Model model, @RequestParam(value="id",required=true) Integer items_id)throws Exception {
241 | public String editItems(Model model)throws Exception {
242 |
243 | //调用service根据商品id查询商品信息
244 | ItemsCustom itemsCustom = itemsService.findItemsById(1);
245 |
246 | //通过形参中的model将model数据传到页面
247 | //相当于modelAndView.addObject方法
248 | model.addAttribute("itemsCustom", itemsCustom);
249 |
250 | return "items/editItems";
251 | }
252 | ```
253 |
254 | 2.redirect重定向
255 |
256 | 商品修改提交后,重定向到商品查询列表。
257 |
258 | redirect重定向特点:浏览器地址栏中的url会变化。修改提交的request数据无法传到重定向的地址。因为重定向后重新进行request(request无法共享)
259 |
260 | ```java
261 | //重定向到商品查询列表
262 | //return "redirect:queryItems.action";
263 | ```
264 |
265 | 3.forward页面转发
266 |
267 | 通过forward进行页面转发,浏览器地址栏url不变,request可以共享。
268 |
269 | ```java
270 | //页面转发
271 | return "forward:queryItems.action";
272 | ```
273 |
274 |
275 |
276 | - 返回void
277 |
278 | 在controller方法形参上可以定义request和response,使用request或response指定响应结果:
279 |
280 | 1.使用request转向页面,如下:
281 |
282 | `request.getRequestDispatcher("页面路径").forward(request, response);`
283 |
284 | 2.也可以通过response页面重定向:
285 |
286 | `response.sendRedirect("url")`
287 |
288 | 3.也可以通过response指定响应结果,例如响应json数据如下:
289 |
290 | ```java
291 | response.setCharacterEncoding("utf-8");
292 | response.setContentType("application/json;charset=utf-8");
293 | response.getWriter().write("json串");
294 | ```
295 |
--------------------------------------------------------------------------------
/springmvc/11 springmvc注解开发之简单参数绑定.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(11)-springmvc注解开发之简单参数绑定
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [spring参数绑定过程](#spring参数绑定过程)
10 | - [默认支持的类型](#默认支持的类型)
11 | - [简单类型](#简单类型)
12 | - [pojo绑定](#pojo绑定)
13 | - [自定义参数绑定实现日期类型绑定](#自定义参数绑定实现日期类型绑定)
14 | - [springmvc和struts2的区别](#springmvc和struts2的区别)
15 |
16 |
17 |
18 | ---
19 |
20 |
21 | 本文主要介绍注解开发的简单参数绑定,包括简单类型、简单pojo以及自定义绑定实现类型转换
22 |
23 | ## spring参数绑定过程
24 |
25 | 从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。
26 |
27 | springmvc中,接收页面提交的数据是通过方法形参来接收。而不是在controller类定义成员变更接收!!!!
28 |
29 | 
30 |
31 |
32 |
33 |
34 | ## 默认支持的类型
35 |
36 | 直接在controller方法形参上定义下边类型的对象,就可以使用这些对象。在参数绑定过程中,如果遇到下边类型直接进行绑定。
37 |
38 | - `HttpServletRequest`:通过request对象获取请求信息
39 | - `HttpServletResponse`:通过response处理响应信息
40 | - `HttpSession`:通过session对象得到session中存放的对象
41 | - `Model/ModelMap`:model是一个接口,modelMap是一个接口实现。作用:将model数据填充到request域。
42 |
43 |
44 | ## 简单类型
45 |
46 | 通过`@RequestParam`对简单类型的参数进行绑定。如果不使用`@RequestParam`,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功。
47 |
48 | 如果使用`@RequestParam`,不用限制request传入参数名称和controller方法的形参名称一致。
49 |
50 | 通过required属性指定参数是否必须要传入,如果设置为true,没有传入参数,报下边错误:
51 |
52 | 
53 |
54 |
55 |
56 |
57 | ```java
58 | @RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
59 | //@RequestParam里边指定request传入参数名称和形参进行绑定。
60 | //通过required属性指定参数是否必须要传入
61 | //通过defaultValue可以设置默认值,如果id参数没有传入,将默认值和形参绑定。
62 | public String editItems(Model model,@RequestParam(value="id",required=true) Integer items_id)throws Exception {
63 |
64 | ```
65 |
66 |
67 | ## pojo绑定
68 |
69 | 页面中input的name和controller的pojo形参中的属性名称一致,将页面中数据绑定到pojo。
70 |
71 | 注意:这里只是要求name和形参的**属性名**一致,而不是要求和形参的**名称**一致,这点不要混淆了,框架会进入形参内部自动匹配pojo类的属性名。(我没看源码,但应该是用反射实现的)
72 |
73 |
74 |
75 | 页面定义:
76 |
77 | ```jsp
78 |
79 |
80 | 商品名称 |
81 | |
82 |
83 |
84 | 商品价格 |
85 | |
86 |
87 | ```
88 |
89 | controller的pojo形参的定义:
90 |
91 | ```java
92 | public class Items {
93 | private Integer id;
94 |
95 | private String name;
96 |
97 | private Float price;
98 |
99 | private String pic;
100 |
101 | private Date createtime;
102 |
103 | private String detail;
104 | ```
105 |
106 |
107 | ## 自定义参数绑定实现日期类型绑定
108 |
109 | 对于controller形参中pojo对象,如果属性中有日期类型,需要自定义参数绑定。
110 |
111 | 将请求日期数据串传成日期类型,要转换的日期类型和pojo中日期属性的类型保持一致。本文示例中,自定义参数绑定将日期串转成java.util.Date类型。
112 |
113 | 需要向处理器适配器中注入自定义的参数绑定组件。
114 |
115 |
116 | - 自定义日期类型绑定
117 |
118 | ```java
119 | public class CustomDateConverter implements Converter{
120 | public Date convert(String s) {
121 | //实现 将日期串转成日期类型(格式是yyyy-MM-dd HH:mm:ss)
122 |
123 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
124 |
125 | try {
126 | //转成直接返回
127 | return simpleDateFormat.parse(s);
128 | } catch (ParseException e) {
129 | // TODO Auto-generated catch block
130 | e.printStackTrace();
131 | }
132 | //如果参数绑定失败返回null
133 | return null;
134 |
135 | }
136 | }
137 | ```
138 |
139 |
140 | - 配置方式
141 |
142 | ```xml
143 |
144 | ```
145 |
146 | ```xml
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | ```
158 |
159 |
160 | ## springmvc和struts2的区别
161 |
162 | - 1.springmvc基于方法开发的,struts2基于类开发的。
163 |
164 | springmvc将url和controller方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。方法执行结束,形参数据销毁。springmvc的controller开发类似service开发。
165 |
166 | - 2.springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。
167 |
168 | - 3.经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。
169 |
--------------------------------------------------------------------------------
/springmvc/12 springmvc注解开发之包装类型参数绑定.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(12)-springmvc注解开发之包装类型参数绑定
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [需求](#需求)
10 | - [实现方法](#实现方法)
11 | - [页面参数和controller方法形参定义](#页面参数和controller方法形参定义)
12 |
13 |
14 |
15 | ---
16 |
17 | 本文主要介绍注解开发的介绍包装类型的参数绑定
18 |
19 |
20 | ## 需求
21 |
22 | 商品查询controller方法中实现商品查询条件传入。
23 |
24 | ## 实现方法
25 |
26 | - 第一种方法:在形参中添加`HttpServletRequest request`参数,通过request接收查询条件参数。
27 | - 第二种方法:在形参中让包装类型的pojo接收查询条件参数。
28 |
29 | 分析:
30 |
31 | 页面传参数的特点:复杂,多样性。条件包括:用户账号、商品编号、订单信息。。。
32 |
33 | 如果将用户账号、商品编号、订单信息等放在简单pojo(属性是简单类型)中,pojo类属性比较多,比较乱。建议使用包装类型的pojo,pojo中属性是pojo。
34 |
35 | ## 页面参数和controller方法形参定义
36 |
37 | - 页面参数:
38 |
39 | 商品名称:``
40 |
41 | **注意:itemsCustom和包装pojo中的属性名一致即可。**
42 |
43 |
44 | - controller方法形参:
45 |
46 | `public ModelAndView queryItems(HttpServletRequest request, ItemsQueryVo itemsQueryVo) throws Exception`
47 |
48 | - 包装类ItemsQueryVo中部分属性:
49 |
50 | ```java
51 | public class ItemsQueryVo {
52 |
53 | //商品信息
54 | private Items items;
55 |
56 | //为了系统 可扩展性,对原始生成的po进行扩展
57 | private ItemsCustom itemsCustom;
58 | ```
59 |
60 | 可见,`ItemsQueryVo`中属性`itemsCustom`和页面参数中一致
61 |
62 |
63 |
--------------------------------------------------------------------------------
/springmvc/13 springmvc注解开发之集合类型参数绑定.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(13)-springmvc注解开发之集合类型参数绑定
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [数组绑定](#数组绑定)
10 | - [需求](#需求)
11 | - [表现层实现](#表现层实现)
12 | - [list绑定](#list绑定)
13 | - [需求](#需求)
14 | - [表现层实现](#表现层实现)
15 | - [map绑定](#map绑定)
16 |
17 |
18 |
19 | ---
20 |
21 |
22 | 本文主要介绍注解开发的集合类型参数绑定,包括数组绑定,list绑定以及map绑定
23 |
24 | ## 数组绑定
25 |
26 | ### 需求
27 |
28 | 商品批量删除,用户在页面选择多个商品,批量删除。
29 |
30 | ### 表现层实现
31 |
32 | 关键:将页面选择(多选)的商品id,传到controller方法的形参,方法形参使用数组接收页面请求的多个商品id。
33 |
34 | - controller方法定义:
35 |
36 | ```java
37 | // 批量删除 商品信息
38 | @RequestMapping("/deleteItems")
39 | public String deleteItems(Integer[] items_id) throws Exception
40 | ```
41 |
42 | - 页面定义:
43 |
44 | ```jsp
45 |
46 |
47 | |
48 | ${item.name } |
49 | ${item.price } |
50 | |
51 | ${item.detail } |
52 |
53 | 修改 |
54 |
55 |
56 |
57 | ```
58 |
59 |
60 |
61 | ## list绑定
62 |
63 | ### 需求
64 |
65 | 通常在需要批量提交数据时,将提交的数据绑定到`list`中,比如:成绩录入(录入多门课成绩,批量提交),
66 |
67 | 本例子需求:批量商品修改,在页面输入多个商品信息,将多个商品信息提交到controller方法中。
68 |
69 | ### 表现层实现
70 |
71 | - controller方法定义:
72 | - 1、进入批量商品修改页面(页面样式参考商品列表实现)
73 | - 2、批量修改商品提交
74 |
75 | 使用List接收页面提交的批量数据,通过包装pojo接收,在包装pojo中定义`list`属性
76 |
77 | ```java
78 | public class ItemsQueryVo {
79 |
80 | //商品信息
81 | private Items items;
82 |
83 | //为了系统 可扩展性,对原始生成的po进行扩展
84 | private ItemsCustom itemsCustom;
85 |
86 | //批量商品信息
87 | private List itemsList;
88 | ```
89 |
90 |
91 | ```java
92 | // 批量修改商品提交
93 | // 通过ItemsQueryVo接收批量提交的商品信息,将商品信息存储到itemsQueryVo中itemsList属性中。
94 | @RequestMapping("/editItemsAllSubmit")
95 | public String editItemsAllSubmit(ItemsQueryVo itemsQueryVo) throws Exception {
96 |
97 | return "success";
98 | }
99 | ```
100 |
101 | - 页面定义:
102 |
103 | ```jsp
104 |
105 |
106 |
107 | |
108 | |
109 | "/> |
110 | |
111 |
112 |
113 |
114 | ```
115 |
116 | name的格式:
117 |
118 | **`对应包装pojo中的list类型属性名`[`下标(从0开始)`].`包装pojo中List类型的属性中pojo的属性名`**
119 |
120 | 例子:
121 |
122 | `"name="itemsList[${status.index }].price"`
123 |
124 |
125 | *可以和包装类型的参数绑定归纳对比一下,其实就是在包装类的pojo基础上多了个下标。只不过包装类参数绑定时,要和包装pojo中的pojo类性的属性名一致,而list参数绑定时,要和包装pojo中的list类型的属性名一致。*
126 |
127 |
128 | ## map绑定
129 |
130 | 也通过在包装pojo中定义map类型属性。
131 |
132 | 在包装类中定义Map对象,并添加get/set方法,action使用包装对象接收。
133 |
134 | - 包装类中定义Map对象如下:
135 |
136 | ```java
137 | Public class QueryVo {
138 | private Map itemInfo = new HashMap();
139 | //get/set方法..
140 | }
141 | ```
142 |
143 | - 页面定义如下:
144 |
145 | ```java
146 |
147 | 学生信息: |
148 |
149 | 姓名:
150 | 年龄:
151 | .. .. ..
152 | |
153 |
154 | ```
155 |
156 |
157 |
158 | - Contrller方法定义如下:
159 |
160 | ```java
161 | public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
162 | System.out.println(queryVo.getStudentinfo());
163 | }
164 | ```
165 |
166 |
167 |
--------------------------------------------------------------------------------
/springmvc/14 springmvc校验.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(14)-springmvc校验
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [校验理解](#校验理解)
10 | - [springmvc校验需求](#springmvc校验需求)
11 | - [环境准备](#环境准备)
12 | - [配置校验器](#配置校验器)
13 | - [添加校验的错误提示信息](#添加校验的错误提示信息)
14 | - [在pojo中添加校验规则](#在pojo中添加校验规则)
15 | - [捕获和显示校验错误信息](#捕获和显示校验错误信息)
16 | - [分组校验](#分组校验)
17 |
18 |
19 |
20 | ---
21 |
22 |
23 | 本文主要介绍springmvc校验,包括环境准备,校验器配置,pojo张添加校验规则,捕获和显示检验错误信息以及分组校验简单示例。
24 |
25 |
26 | ## 校验理解
27 |
28 | 项目中,通常使用较多是前端的校验,比如页面中js校验。对于安全要求较高点建议在服务端进行校验。
29 |
30 | 服务端校验:
31 |
32 | - 控制层conroller:校验页面请求的参数的合法性。在服务端控制层conroller校验,不区分客户端类型(浏览器、手机客户端、远程调用)
33 | - 业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数。
34 | - 持久层dao:一般是不校验的。
35 |
36 | ## springmvc校验需求
37 |
38 | springmvc使用hibernate的校验框架validation(和hibernate没有任何关系)。
39 |
40 | 校验思路:
41 |
42 | 页面提交请求的参数,请求到controller方法中,使用validation进行校验。如果校验出错,将错误信息展示到页面。
43 |
44 | 具体需求:
45 |
46 | 商品修改,添加校验(校验商品名称长度,生产日期的非空校验),如果校验出错,在商品修改页面显示错误信息。
47 |
48 |
49 | ## 环境准备
50 |
51 | 我们需要三个jar包:
52 |
53 | - hibernate-validator.jar
54 | - jboss-logging.jar
55 | - validation-api.jar
56 |
57 | 这里我们添加maven依赖
58 |
59 | ```xml
60 |
61 |
62 | org.hibernate
63 | hibernate-validator
64 | 5.2.4.Final
65 |
66 | ```
67 |
68 | 查看maven依赖树
69 |
70 | ```
71 | [INFO] \- org.hibernate:hibernate-validator:jar:5.2.4.Final:compile
72 | [INFO] +- javax.validation:validation-api:jar:1.1.0.Final:compile
73 | [INFO] +- org.jboss.logging:jboss-logging:jar:3.2.1.Final:compile
74 | [INFO] \- com.fasterxml:classmate:jar:1.1.0:compile
75 | ```
76 |
77 | 可以看到,另外两个jar包被`hibernate-validator`依赖,所以不用再额外添加了。
78 |
79 |
80 | ## 配置校验器
81 |
82 |
83 | - 在springmvc.xml中添加
84 |
85 | ```xml
86 |
87 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
97 |
98 |
99 |
100 | classpath:CustomValidationMessages
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | ```
109 |
110 | - 校验器注入到处理器适配器中
111 |
112 | ```xml
113 |
115 |
116 | ```
117 |
118 | - 在CustomValidationMessages.properties配置校验错误信息:
119 |
120 | ```
121 | #添加校验的错误提示信息
122 | items.name.length.error=请输入1到30个字符的商品名称
123 | items.createtime.isNUll=请输入商品的生产日期
124 | ```
125 |
126 |
127 | ## 在pojo中添加校验规则
128 |
129 | 在ItemsCustom.java中添加校验规则:
130 |
131 |
132 | ```java
133 | public class Items {
134 | private Integer id;
135 | //校验名称在1到30字符中间
136 | //message是提示校验出错显示的信息
137 | //groups:此校验属于哪个分组,groups可以定义多个分组
138 | @Size(min=1,max=30,message="{items.name.length.error}")
139 | private String name;
140 |
141 | private Float price;
142 |
143 | private String pic;
144 |
145 | //非空校验
146 | @NotNull(message="{items.createtime.isNUll}")
147 | private Date createtime;
148 | ```
149 |
150 |
151 | ## 捕获和显示校验错误信息
152 |
153 | ```java
154 | @RequestMapping("/editItemsSubmit")
155 | public String editItemsSubmit(
156 | Model model,
157 | HttpServletRequest request,
158 | Integer id,
159 | @Validated ItemsCustom itemsCustom,
160 | BindingResult bindingResult)throws Exception {
161 | ```
162 |
163 | - 在controller中将错误信息传到页面即可
164 |
165 | ```
166 | //获取校验错误信息
167 | if(bindingResult.hasErrors()){
168 | // 输出错误信息
169 | List allErrors = bindingResult.getAllErrors();
170 |
171 | for (ObjectError objectError :allErrors){
172 | // 输出错误信息
173 | System.out.println(objectError.getDefaultMessage());
174 | }
175 | // 将错误信息传到页面
176 | model.addAttribute("allErrors", allErrors);
177 |
178 | //可以直接使用model将提交pojo回显到页面
179 | model.addAttribute("items", itemsCustom);
180 |
181 | // 出错重新到商品修改页面
182 | return "items/editItems";
183 | }
184 | ```
185 |
186 | - 页面显示错误信息:
187 |
188 | ```jsp
189 |
190 |
191 |
192 | ${ error.defaultMessage}
193 |
194 |
195 | ```
196 |
197 | ## 分组校验
198 |
199 | - 需求:
200 | - 在pojo中定义校验规则,而pojo是被多个controller所共用,当不同的controller方法对同一个pojo进行校验,但是每个controller方法需要不同的校验
201 | - 解决方法:
202 | - 定义多个校验分组(其实是一个java接口),分组中定义有哪些规则
203 | - 每个controller方法使用不同的校验分组
204 |
205 |
206 |
207 |
208 | 1.校验分组
209 |
210 | ```java
211 | public interface ValidGroup1 {
212 | //接口中不需要定义任何方法,仅是对不同的校验规则进行分组
213 | //此分组只校验商品名称长度
214 |
215 | }
216 | ```
217 |
218 |
219 | 2.在校验规则中添加分组
220 |
221 | ```java
222 | //校验名称在1到30字符中间
223 | //message是提示校验出错显示的信息
224 | //groups:此校验属于哪个分组,groups可以定义多个分组
225 | @Size(min=1,max=30,message="{items.name.length.error}",groups = {ValidGroup1.class})
226 | private String name;
227 | ```
228 |
229 | 3.在controller方法使用指定分组的校验
230 |
231 | ```java
232 | // value={ValidGroup1.class}指定使用ValidGroup1分组的校验
233 | @RequestMapping("/editItemsSubmit")
234 | public String editItemsSubmit(
235 | Model model,
236 | HttpServletRequest request,
237 | Integer id,
238 | @Validated(value = ValidGroup1.class)ItemsCustom itemsCustom,
239 | BindingResult bindingResult)throws Exception {
240 | ```
241 |
242 |
243 |
--------------------------------------------------------------------------------
/springmvc/15 数据回显.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(15)-数据回显
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [pojo数据回显方法](#pojo数据回显方法)
10 | - [简单类型数据回显](#简单类型数据回显)
11 |
12 |
13 |
14 | ---
15 |
16 |
17 |
18 | 本文介绍springmvc中数据回显的几种实现方法
19 |
20 |
21 | 数据回显:提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面。
22 |
23 |
24 | ## pojo数据回显方法
25 |
26 | 1.springmvc默认对pojo数据进行回显。
27 |
28 | **pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写)**
29 |
30 | 使用`@ModelAttribute`指定pojo回显到页面在request中的key
31 |
32 | 2.`@ModelAttribute`还可以将方法的返回值传到页面
33 |
34 | 在商品查询列表页面,通过商品类型查询商品信息。在controller中定义商品类型查询方法,最终将商品类型传到页面。
35 |
36 | ```java
37 | // 商品分类
38 | //itemtypes表示最终将方法返回值放在request中的key
39 | @ModelAttribute("itemtypes")
40 | public Map getItemTypes() {
41 |
42 | Map itemTypes = new HashMap();
43 | itemTypes.put("101", "数码");
44 | itemTypes.put("102", "母婴");
45 |
46 | return itemTypes;
47 | }
48 | ```
49 |
50 | 页面上可以得到itemTypes数据。
51 |
52 |
53 | ```jsp
54 |
55 | 商品名称:
56 | 商品类型:
57 |
62 | |
63 | ```
64 |
65 | 3.使用最简单方法使用model,可以不用`@ModelAttribute`
66 |
67 | ```java
68 | //可以直接使用model将提交pojo回显到页面
69 | //model.addAttribute("items", itemsCustom);
70 | ```
71 |
72 |
73 | ## 简单类型数据回显
74 |
75 | 使用最简单方法使用model
76 |
77 | `model.addAttribute("id", id);`
78 |
79 |
80 |
--------------------------------------------------------------------------------
/springmvc/1533949939501.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/1533949939501.png
--------------------------------------------------------------------------------
/springmvc/16 异常处理器.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(16)-异常处理器
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [异常处理思路](#异常处理思路)
10 | - [自定义异常类](#自定义异常类)
11 | - [全局异常处理器](#全局异常处理器)
12 | - [错误页面](#错误页面)
13 | - [在springmvc.xml配置全局异常处理器](#在springmvcxml配置全局异常处理器)
14 | - [异常测试](#异常测试)
15 |
16 |
17 |
18 | ---
19 |
20 |
21 | 本文主要介绍springmvc中异常处理的思路,并展示如何自定义异常处理类以及全局异常处理器的配置
22 |
23 |
24 | ## 异常处理思路
25 |
26 | 系统中异常包括两类:
27 |
28 | - 预期异常
29 | - 运行时异常RuntimeException
30 |
31 | 前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
32 |
33 | 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:
34 |
35 | 
36 |
37 | springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
38 |
39 |
40 | ## 自定义异常类
41 |
42 | 对不同的异常类型定义异常类,继承Exception。
43 |
44 | ```java
45 | package com.iot.learnssm.firstssm.exception;
46 |
47 | /**
48 | * Created by brian on 2016/3/7.
49 | *
50 | * 系统 自定义异常类,针对预期的异常,需要在程序中抛出此类的异常
51 | */
52 | public class CustomException extends Exception{
53 | //异常信息
54 | public String message;
55 |
56 | public CustomException(String message){
57 | super(message);
58 | this.message = message;
59 | }
60 |
61 | public String getMessage() {
62 | return message;
63 | }
64 |
65 | public void setMessage(String message) {
66 | this.message = message;
67 | }
68 | }
69 | ```
70 |
71 | ## 全局异常处理器
72 |
73 | 思路:
74 |
75 | 系统遇到异常,在程序中手动抛出,dao抛给service、service给controller、controller抛给前端控制器,前端控制器调用全局异常处理器。
76 |
77 | 全局异常处理器处理思路:
78 |
79 | 解析出异常类型
80 |
81 | - 如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示
82 | - 如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
83 |
84 | springmvc提供一个`HandlerExceptionResolver`接口
85 |
86 |
87 | ```java
88 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
89 | //handler就是处理器适配器要执行Handler对象(只有method)
90 | //解析出异常类型
91 | //如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示
92 | //String message = null;
93 | //if(ex instanceof CustomException){
94 | //message = ((CustomException)ex).getMessage();
95 | //}else{
96 | ////如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
97 | //message="未知错误";
98 | //}
99 |
100 | //上边代码变为
101 | CustomException customException;
102 | if(ex instanceof CustomException){
103 | customException = (CustomException)ex;
104 | }else{
105 | customException = new CustomException("未知错误");
106 | }
107 |
108 | //错误信息
109 | String message = customException.getMessage();
110 |
111 | ModelAndView modelAndView = new ModelAndView();
112 |
113 | //将错误信息传到页面
114 | modelAndView.addObject("message", message);
115 |
116 | //指向错误页面
117 | modelAndView.setViewName("error");
118 |
119 | return modelAndView;
120 |
121 | }
122 | }
123 | ```
124 |
125 | ## 错误页面
126 |
127 | ```jsp
128 | <%--
129 | Created by IntelliJ IDEA.
130 | User: Brian
131 | Date: 2016/3/4
132 | Time: 10:51
133 | To change this template use File | Settings | File Templates.
134 | --%>
135 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
136 |
137 |
138 | 错误提示
139 |
140 |
141 | ${message}
142 |
143 |
144 | ```
145 |
146 | ## 在springmvc.xml配置全局异常处理器
147 |
148 | ```xml
149 |
152 |
153 | ```
154 |
155 | 全局异常处理器只有一个,配置多个也没用。
156 |
157 |
158 |
159 | ## 异常测试
160 |
161 | 在controller、service、dao中任意一处需要手动抛出异常。如果是程序中手动抛出的异常,在错误页面中显示自定义的异常信息,如果不是手动抛出异常说明是一个运行时异常,在错误页面只显示“未知错误”。
162 |
163 | - 在商品修改的controller方法中抛出异常 .
164 |
165 | ```java
166 | public String editItems(Model model,@RequestParam(value="id",required=true) Integer items_id)throws Exception {
167 |
168 | //调用service根据商品id查询商品信息
169 | ItemsCustom itemsCustom = itemsService.findItemsById(items_id);
170 |
171 | //判断商品是否为空,根据id没有查询到商品,抛出异常,提示用户商品信息不存在
172 | if(itemsCustom == null){
173 | throw new CustomException("修改的商品信息不存在!");
174 | }
175 |
176 | //通过形参中的model将model数据传到页面
177 | //相当于modelAndView.addObject方法
178 | model.addAttribute("items", itemsCustom);
179 |
180 | return "items/editItems";
181 | }
182 | ```
183 |
184 | - 在service接口中抛出异常:
185 |
186 | ```java
187 | public ItemsCustom findItemsById(Integer id) throws Exception {
188 | Items items = itemsMapper.selectByPrimaryKey(id);
189 | if(items==null){
190 | throw new CustomException("修改的商品信息不存在!");
191 | }
192 | //中间对商品信息进行业务处理
193 | //....
194 | //返回ItemsCustom
195 | ItemsCustom itemsCustom = null;
196 | //将items的属性值拷贝到itemsCustom
197 | if(items!=null){
198 | itemsCustom = new ItemsCustom();
199 | BeanUtils.copyProperties(items, itemsCustom);
200 | }
201 |
202 | return itemsCustom;
203 | }
204 | ```
205 |
206 |
207 | - 如果与业务功能相关的异常,建议在service中抛出异常。
208 | - 与业务功能没有关系的异常,建议在controller中抛出。
209 |
210 | 上边的功能,建议在service中抛出异常。
211 |
--------------------------------------------------------------------------------
/springmvc/17 上传图片.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(17)-上传图片
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [springmvc中对多部件类型解析](#springmvc中对多部件类型解析)
10 | - [加入上传图片的jar](#加入上传图片的jar)
11 | - [创建图片虚拟目录存储图片](#创建图片虚拟目录存储图片)
12 | - [上传图片代码](#上传图片代码)
13 |
14 |
15 |
16 | ---
17 |
18 |
19 | 本文展示如何在springmvc中上传图片
20 |
21 |
22 | ## springmvc中对多部件类型解析
23 |
24 | 在修改商品页面,添加上传商品图片功能。
25 |
26 | 在页面form中提交`enctype="multipart/form-data"`的数据时,需要springmvc对multipart类型的数据进行解析。
27 |
28 | 在springmvc.xml中配置multipart类型解析器。
29 |
30 | ```xml
31 |
32 |
34 |
35 |
36 | 5242880
37 |
38 |
39 | ```
40 |
41 | ## 加入上传图片的jar
42 |
43 | 添加依赖
44 |
45 | ```xml
46 |
47 |
48 | commons-fileupload
49 | commons-fileupload
50 | 1.3.1
51 |
52 | ```
53 |
54 | 依赖树
55 |
56 | ```
57 | [INFO] \- commons-fileupload:commons-fileupload:jar:1.3.1:compile
58 | [INFO] \- commons-io:commons-io:jar:2.2:compile
59 | ```
60 |
61 | 可以看到,其实还间接依赖了`commons-io:commons-io:jar`
62 |
63 |
64 | ## 创建图片虚拟目录存储图片
65 |
66 | 参考我之前的博文
67 |
68 | > [在intellij IDEA中为web应用创建图片虚拟目录(详细截图)](http://blog.csdn.net/h3243212/article/details/50819218)
69 |
70 |
71 | 也可以直接修改tomcat的配置,在conf/server.xml文件,添加虚拟目录.
72 |
73 | 注意:在图片虚拟目录中,一定将图片目录分级创建(提高i/o性能),一般我们采用按日期(年、月、日)进行分级创建。
74 |
75 | ## 上传图片代码
76 |
77 | - 页面
78 |
79 | ```jsp
80 |
81 | 商品图片 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | |
89 |
90 | ```
91 |
92 | - controller方法
93 |
94 | 修改:商品修改controller方法:
95 |
96 | ```java
97 | @RequestMapping("/editItemsSubmit")
98 | public String editItemsSubmit(
99 | Model model,
100 | HttpServletRequest request,
101 | Integer id,
102 | @ModelAttribute("items")
103 | @Validated(value = ValidGroup1.class)ItemsCustom itemsCustom,
104 | BindingResult bindingResult,
105 | MultipartFile items_pic
106 | )throws Exception {
107 | ```
108 |
109 | ```java
110 | //原始名称
111 | String originalFilename = items_pic.getOriginalFilename();
112 | //上传图片
113 | if(items_pic!=null && originalFilename!=null && originalFilename.length()>0){
114 |
115 | //存储图片的物理路径
116 | String pic_path = "D:\\tmp\\";
117 |
118 |
119 | //新的图片名称
120 | String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
121 | //新图片
122 | File newFile = new File(pic_path+newFileName);
123 |
124 | //将内存中的数据写入磁盘
125 | items_pic.transferTo(newFile);
126 |
127 | //将新图片名称写到itemsCustom中
128 | itemsCustom.setPic(newFileName);
129 |
130 | }
131 | ```
132 |
133 |
134 |
--------------------------------------------------------------------------------
/springmvc/18 json数据交互.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(18)-json数据交互
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [springmvc进行json交互](#springmvc进行json交互)
10 | - [环境准备](#环境准备)
11 | - [添加json转换的依赖](#添加json转换的依赖)
12 | - [配置json转换器](#配置json转换器)
13 | - [json交互测试](#json交互测试)
14 | - [输入json串,输出是json串](#输入json串,输出是json串)
15 | - [输入key/value,输出是json串](#输入keyvalue,输出是json串)
16 |
17 |
18 |
19 | ---
20 |
21 |
22 |
23 | 本文主要介绍如何在springmvc中进行json数据的交互,先是环境准备和配置,然后分别展示了“输入json串,输出是json串”和“输入key/value,输出是json串”两种情况下的交互
24 |
25 |
26 | ## springmvc进行json交互
27 |
28 | json数据格式在接口调用中、html页面中较常用,json格式比较简单,解析还比较方便。
29 |
30 | 比如:webservice接口,传输json数据.
31 |
32 | 
33 |
34 |
35 |
36 | - 请求json、输出json,要求请求的是json串,所以在前端页面中需要将请求的内容转成json,不太方便。
37 | - 请求key/value、输出json。此方法比较常用。
38 |
39 | ## 环境准备
40 |
41 | ### 添加json转换的依赖
42 |
43 | 最开始我少了`jackson-databind`依赖,程序各种报错。
44 |
45 | ```xml
46 |
47 |
48 |
49 | com.fasterxml.jackson.core
50 | jackson-databind
51 | 2.7.2
52 |
53 |
54 |
55 | org.codehaus.jackson
56 | jackson-mapper-asl
57 | 1.9.13
58 |
59 | ```
60 |
61 | 查看依赖树
62 |
63 | ```
64 | [INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.7.2:compile
65 | [INFO] | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.7.0:compile
66 | [INFO] | \- com.fasterxml.jackson.core:jackson-core:jar:2.7.2:compile
67 | [INFO] \- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.13:compile
68 | [INFO] \- org.codehaus.jackson:jackson-core-asl:jar:1.9.13:compile
69 | ```
70 |
71 |
72 | ### 配置json转换器
73 |
74 | 在注解适配器中加入`messageConverters`
75 |
76 | ```xml
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | ```
87 |
88 | **注意:如果使用``则不用定义上边的内容。**
89 |
90 | ## json交互测试
91 |
92 | 显示两个按钮分别测试
93 |
94 | - jsp页面
95 |
96 | ```jsp
97 | <%--
98 | Created by IntelliJ IDEA.
99 | User: brian
100 | Date: 2016/3/7
101 | Time: 20:49
102 | To change this template use File | Settings | File Templates.
103 | --%>
104 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
105 |
106 |
107 |
108 | json交互测试
109 |
110 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | ```
123 |
124 | - controller
125 |
126 |
127 | ```java
128 | @Controller
129 | public class JsonTest {
130 | 省略
131 | }
132 | ```
133 |
134 | - 测试结果
135 |
136 |
137 | ### 输入json串,输出是json串
138 |
139 | 使用jquery的ajax提交json串,对输出的json结果进行解析。
140 |
141 | - jsp页面
142 |
143 | ```jsp
144 | //请求json,输出是json
145 | function requestJson(){
146 |
147 | $.ajax({
148 | type:'post',
149 | url:'${pageContext.request.contextPath }/requestJson.action',
150 | contentType:'application/json;charset=utf-8',
151 | //数据格式是json串,商品信息
152 | data:'{"name":"手机","price":999}',
153 | success:function(data){//返回json结果
154 | alert(data);
155 | }
156 |
157 | });
158 |
159 | }
160 | ```
161 |
162 | - controller
163 |
164 | ```java
165 | //请求json串(商品信息),输出json(商品信息)
166 | //@RequestBody将请求的商品信息的json串转成itemsCustom对象
167 | //@ResponseBody将itemsCustom转成json输出
168 | @RequestMapping("/requestJson")
169 | public @ResponseBody ItemsCustom requestJson(@RequestBody ItemsCustom itemsCustom){
170 |
171 | //@ResponseBody将itemsCustom转成json输出
172 | return itemsCustom;
173 | }
174 | ```
175 |
176 | - 测试结果
177 |
178 | 
179 |
180 |
181 |
182 | 可以看到,request和response的HTTP头的Content-Type都是`application/json;charset=utf-8`
183 |
184 |
185 | ### 输入key/value,输出是json串
186 |
187 | 使用jquery的ajax提交key/value串,对输出的json结果进行解析
188 |
189 | - jsp页面
190 |
191 | ```jsp
192 | //请求key/value,输出是json
193 | function responseJson(){
194 |
195 | $.ajax({
196 | type:'post',
197 | url:'${pageContext.request.contextPath }/responseJson.action',
198 | //请求是key/value这里不需要指定contentType,因为默认就 是key/value类型
199 | //contentType:'application/json;charset=utf-8',
200 | //数据格式是json串,商品信息
201 | data:'name=手机&price=999',
202 | success:function(data){//返回json结果
203 | alert(data.name);
204 | }
205 |
206 | });
207 |
208 | }
209 | ```
210 |
211 | - controller
212 |
213 |
214 | ```java
215 | //请求key/value,输出json
216 | @RequestMapping("/responseJson")
217 | public @ResponseBody ItemsCustom responseJson(ItemsCustom itemsCustom){
218 |
219 | //@ResponseBody将itemsCustom转成json输出
220 | return itemsCustom;
221 | }
222 | ```
223 |
224 | - 测试结果
225 |
226 | 
227 |
228 |
229 |
230 |
231 | 可以看到,key/value键值对的默认Content-Type是`application/x-www-form-urlencoded`,同时,我们收到了响应“手机”
232 |
233 |
234 |
--------------------------------------------------------------------------------
/springmvc/19 RESTful支持.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(19)-RESTful支持
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [概念](#概念)
10 | - [REST的例子](#rest的例子)
11 | - [controller](#controller)
12 | - [REST方法的前端控制器配置](#rest方法的前端控制器配置)
13 | - [对静态资源的解析](#对静态资源的解析)
14 |
15 |
16 |
17 | ---
18 |
19 |
20 | 本文介绍RESTful的概念,并通过一个小例子展示如何编写RESTful风格的controller和配置前端控制器,最后展示静态资源的解析
21 |
22 |
23 | ## 概念
24 |
25 | 首先附上两篇博客链接
26 |
27 | >* [理解RESTful架构 - 阮一峰的网络日志](http://zqpythonic.qiniucdn.com/data/20110912210739/index.html)
28 | >* [RESTful API 设计指南- 阮一峰的网络日志](http://www.ruanyifeng.com/blog/2014/05/restful_api.html)
29 |
30 |
31 | RESTful架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
32 |
33 | RESTful(即Representational State Transfer的缩写)其实是一个开发理念,是对http的很好的诠释。
34 |
35 | 1.对url进行规范,写RESTful格式的url
36 |
37 | - 非REST的url:`http://...../queryItems.action?id=001&type=T01`
38 | - REST的url风格:`http://..../items/001`
39 |
40 | 特点:url简洁,将参数通过url传到服务端
41 |
42 | 2.http的方法规范
43 |
44 | 不管是删除、添加、更新,等等。使用url是一致的,如果进行删除,需要设置http的方法为delete,其他同理。
45 |
46 | 后台controller方法:判断http方法,如果是delete执行删除,如果是post执行添加。
47 |
48 | 3.对http的contentType规范
49 |
50 | 请求时指定contentType,要json数据,设置成json格式的type。
51 |
52 |
53 | ## REST的例子
54 |
55 | 查询商品信息,返回json数据。
56 |
57 | ### controller
58 |
59 | 定义方法,进行url映射使用REST风格的url,将查询商品信息的id传入controller .
60 |
61 | 输出json使用`@ResponseBody`将java对象输出json。
62 |
63 | ```java
64 | //查询商品信息,输出json
65 | //itemsView/{id}里边的{id}表示占位符,通过@PathVariable获取占位符中的参数,
66 | //@PathVariable中名称要和占位符一致,形参名无需和其一致
67 | //如果占位符中的名称和形参名一致,在@PathVariable可以不指定名称
68 | @RequestMapping("/itemsView/{id}")
69 | public @ResponseBody ItemsCustom itemsView(@PathVariable("id") Integer items_id)throws Exception{
70 |
71 | //调用service查询商品信息
72 | ItemsCustom itemsCustom = itemsService.findItemsById(items_id);
73 |
74 | return itemsCustom;
75 |
76 | }
77 | ```
78 |
79 | `@RequestMapping(value="/ itemsView/{id}")`:`{×××}`占位符,请求的URL可以是`/viewItems/1`或`/viewItems/2`,通过在方法中使用`@PathVariable`获取{×××}中的×××变量。`@PathVariable`用于将请求URL中的模板变量映射到功能处理方法的参数上。
80 |
81 | 如果`@RequestMapping`中表示为`/itemsView/{id}`,id和形参名称一致,`@PathVariable`不用指定名称。
82 |
83 |
84 | ### REST方法的前端控制器配置
85 |
86 | ```xml
87 |
88 |
89 | springmvc_rest
90 | org.springframework.web.servlet.DispatcherServlet
91 |
92 |
93 | contextConfigLocation
94 | classpath:spring/springmvc.xml
95 |
96 |
97 |
98 |
99 | springmvc_rest
100 | /
101 |
102 | ```
103 |
104 |
105 |
106 |
107 |
108 | ## 对静态资源的解析
109 |
110 | 配置前端控制器的url-parttern中指定`/`,对静态资源的解析会出现问题,报404错误。
111 |
112 |
113 | 在springmvc.xml中添加静态资源解析方法。
114 |
115 | ```xml
116 |
119 |
120 | ```
121 |
122 | 这时访问`http://localhost:8080/ssm1/js/jquery-1.4.4.min.js`,可以在浏览器中看到js的内容
123 |
--------------------------------------------------------------------------------
/springmvc/22 springmvc开发小结.md:
--------------------------------------------------------------------------------
1 | # springmvc学习笔记(22)-springmvc开发小结
2 |
3 | 标签: springmvc
4 |
5 | ---
6 |
7 | **Contents**
8 |
9 | - [springmvc框架](#springmvc框架)
10 | - [注解开发](#注解开发)
11 | - [使用注解方式的处理器映射器和适配器](#使用注解方式的处理器映射器和适配器)
12 | - [注解开发中参数绑定](#注解开发中参数绑定)
13 | - [springmvc和struts2区别](#springmvc和struts2区别)
14 | - [校验](#校验)
15 | - [数据回显](#数据回显)
16 | - [异常处理](#异常处理)
17 | - [上传图片](#上传图片)
18 | - [json数据交互](#json数据交互)
19 | - [RESTful支持](#restful支持)
20 | - [拦截器](#拦截器)
21 | - [拦截器定义](#拦截器定义)
22 | - [拦截器的配置](#拦截器的配置)
23 | - [拦截器测试及其应用](#拦截器测试及其应用)
24 |
25 |
26 |
27 | ---
28 |
29 | 本文对springmvc系列博文进行小结
30 |
31 |
32 | ## springmvc框架
33 |
34 | 
35 |
36 | - `DispatcherServlet`前端控制器:接收request,进行response
37 | - **`HandlerMapping`处理器映射器**:根据url查找Handler。(可以通过xml配置方式,注解方式)
38 | - **`HandlerAdapter`处理器适配器**:根据特定规则去执行Handler,编写Handler时需要按照HandlerAdapter的要求去编写。
39 | - **`Handler`处理器**(后端控制器):需要程序员去编写,**常用注解开发方式**。
40 | - Handler处理器执行后结果是`ModelAndView`,具体开发时`Handler`返回方法值类型包括:`ModelAndView`、`String`(逻辑视图名)、`void`(通过在Handler形参中添加request和response,类似原始 servlet开发方式,注意:可以通过指定response响应的结果类型实现json数据输出)
41 | - `View Resolver`视图解析器:根据逻辑视图名生成真正的视图(在springmvc中使用View对象表示)
42 | - `View`视图:jsp页面,仅是数据展示,没有业务逻辑。
43 |
44 |
45 |
46 | ## 注解开发
47 |
48 | ### 使用注解方式的处理器映射器和适配器
49 |
50 | ```xml
51 |
52 |
53 |
54 |
55 | ```
56 |
57 | 在实际开发,使用``代替上边处理器映射器和适配器配置。
58 |
59 | - `@controller`注解必须要加,作用标识类是一个Handler处理器。
60 | - `@requestMapping`注解必须要加,作用:
61 | - 1、对url和Handler的**方法**进行映射。
62 | - 2、可以窄化请求映射,设置Handler的根路径,url就是根路径+子路径请求方式
63 | - 3、可以限制http请求的方法
64 |
65 |
66 | 映射成功后,springmvc框架生成一个Handler对象,对象中只包括 一个映射成功的method。
67 |
68 | ### 注解开发中参数绑定
69 |
70 | 将request请求过来的key/value的数据(理解一个串),通过转换(参数绑定的一部分),将key/value串转成形参,将转换后的结果传给形参(整个参数绑定过程)。
71 |
72 | springmvc所支持参数绑定:
73 |
74 | - 1、默认支持很多类型:`HttpServletRequest`、`response`、`session`、`model/modelMap`(将模型数据填充到request域)
75 | - 2、支持简单数据类型,整型、字符串、日期..等
76 | - 只要保证request请求的参数名和形参名称一致,自动绑定成功
77 | - 如果request请求的参数名和形参名称不一致,可以使用`@RequestParam`(指定request请求的参数名),`@RequestParam`加在形参的前边。
78 | - 3、支持pojo类型
79 | - 只要保证request请求的参数名称和pojo中的属性名一致,自动将request请求的参数设置到pojo的属性中。
80 | - 4、包装类型pojo参数绑定
81 | - 第一种方法:在形参中添加`HttpServletRequest request`参数,通过request接收查询条件参数。
82 | - 第二种方法:在形参中让包装类型的pojo接收查询条件参数。
83 | - 5、集合类型参数绑定
84 | - 数组绑定:方法形参使用数组接收页面请求的多个参数
85 | - list绑定:使用List接收页面提交的批量数据,通过包装pojo接收,在包装pojo中定义list属性
86 | - map绑定:在包装类中定义Map对象,并添加`get/set`方法,action使用包装对象接收
87 |
88 | *注意:形参中即有pojo类型又有简单类型,参数绑定互不影响。*
89 |
90 |
91 | 自定义参数绑定
92 |
93 | - 日期类型绑定自定义:
94 |
95 | 定义的`Converter<源类型,目标类型>`接口实现类,比如:`Converter`,表示:将请求的日期数据串转成java中的日期类型。
96 |
97 | *注意:要转换的目标类型一定和接收的pojo中的属性类型一致。*
98 |
99 | 将定义的Converter实现类注入到处理器适配器中。
100 |
101 | ```xml
102 |
103 |
104 |
105 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | ```
115 |
116 |
117 | ### springmvc和struts2区别
118 |
119 | springmvc面向方法开发的(更接近service接口的开发方式),struts2面向类开发。
120 |
121 | springmvc可以单例开发,struts2只能是多例开发。
122 |
123 |
124 | ## 校验
125 |
126 | 服务端校验:
127 |
128 | - 控制层conroller:校验页面请求的参数的合法性。在服务端控制层conroller校验,不区分客户端类型(浏览器、手机客户端、远程调用)
129 | - 业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数。
130 | - 持久层dao:一般是不校验的。
131 |
132 | 一般使用hibernate的校验框架,依赖`hibernate-validator.jar`,`jboss-logging.jar`,`validation-api.jar`这几个jar包
133 |
134 | 开发步骤
135 |
136 | - 在springmvc.xml中添加校验器
137 | - 校验器注入到处理器适配器中
138 | - 在CustomValidationMessages.properties配置校验错误信息
139 | - 在pojo中添加校验规则
140 | - 在控制器中对参数注解`@Validated`来捕获和显示校验错误信息
141 |
142 | 分组校验
143 |
144 | - 定义校验分组
145 | - 在校验规则中添加分组
146 | - 在controller方法使用指定分组的校验
147 |
148 | ## 数据回显
149 |
150 | 数据回显有三种方法
151 |
152 | - 1.springmvc默认对pojo数据进行回显。
153 | - pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写)
154 | - 使用`@ModelAttribute`指定pojo回显到页面在request中的key
155 | - 2.`@ModelAttribute`还可以将方法的返回值传到页面
156 | - 3.使用最简单方法使用model,可以不用`@ModelAttribute`
157 |
158 |
159 | ## 异常处理
160 |
161 | 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。
162 |
163 | springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
164 |
165 |
166 | 全局异常处理器处理思路:
167 |
168 | 解析出异常类型
169 |
170 | - 如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示
171 | - 如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
172 |
173 | 抛出异常的位置
174 |
175 | - 如果与业务功能相关的异常,建议在service中抛出异常。
176 | - 与业务功能没有关系的异常,建议在controller中抛出。
177 |
178 | ## 上传图片
179 |
180 | 开发步骤
181 |
182 | - 在页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart类型的数据进行解析。
183 | - 在springmvc.xml中配置multipart类型解析器
184 | - 加入上传图片的jar:`commons-fileupload`
185 | - 创建图片虚拟目录存储图片
186 |
187 | ## json数据交互
188 |
189 | 两种json数据交互的形式:
190 |
191 | - 请求json、输出json,要求请求的是json串,所以在前端页面中需要将请求的内容转成json,不太方便。
192 | - 请求key/value、输出json。此方法比较常用。
193 |
194 | 需要的依赖:
195 |
196 | - `jackson-databind`
197 | - `jackson-mapper-asl`
198 |
199 |
200 |
201 | 在注解适配器中加入`messageConverters`
202 |
203 | ```xml
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 | ```
214 |
215 | **注意:如果使用``则不用定义上边的内容。**
216 |
217 | 在controller的返回值上加注解`@ResponseBody`来将java对象输出json,返回json格式数据
218 |
219 |
220 | ## RESTful支持
221 |
222 | `@RequestMapping(value="/ itemsView/{id}")`:`{×××}`占位符,请求的URL可以是`/viewItems/1`或`/viewItems/2`,通过在方法中使用`@PathVariable`获取{×××}中的×××变量。`@PathVariable`用于将请求URL中的模板变量映射到功能处理方法的参数上。
223 |
224 | 如果`@RequestMapping`中表示为`/itemsView/{id}`,id和形参名称一致,`@PathVariable`不用指定名称。
225 |
226 | 同时需要配置前端控制器。若要访问静态资源,还需在springmvc.xml中添加静态资源解析方法,如``
227 |
228 | ## 拦截器
229 |
230 | ### 拦截器定义
231 |
232 | 定义拦截器,实现`HandlerInterceptor`接口。接口中提供三个方法。可以从名称和参数看出各个接口的顺序和作用
233 |
234 | - `public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception`
235 | - 参数最少,只有三个
236 | - 进入 Handler方法之前执行
237 | - 用于身份认证、身份授权。比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
238 | - `public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception`
239 | - 多了一个modelAndView参数
240 | - 进入Handler方法之后,返回modelAndView之前执行
241 | - 应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
242 | - `public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception`
243 | - 多了一个Exception的类型的参数
244 | - 执行Handler完成执行此方法
245 | - 应用场景:统一异常处理,统一日志处理
246 |
247 | ### 拦截器的配置
248 |
249 | - 针对HandlerMapping配置(一般不推荐)
250 | - springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该HandlerMapping映射成功的handler最终使用该拦截器
251 | - 类似全局的拦截器
252 | - springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。
253 |
254 |
255 | ### 拦截器测试及其应用
256 |
257 | 链式执行测试
258 |
259 | - 两个拦截器都放行
260 | - preHandle方法按顺序执行,postHandle和afterCompletion按拦截器配置的逆向顺序执行
261 | - 拦截器1放行,拦截器2不放行
262 | - 拦截器1放行,拦截器2 preHandle才会执行。
263 | - 拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。
264 | - 只要有一个拦截器不放行,postHandle不会执行。
265 | - 两个拦截器都不放
266 | - 拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。
267 | - 拦截器1 preHandle不放行,拦截器2不执行。
268 |
269 | 应用
270 |
271 | - 统一日志处理拦截器,需要该拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。
272 | - 登陆认证拦截器,放在拦截器链接中第一个位置。权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过后才校验权限,当然登录认证拦截器要放在统一日志处理拦截器后面)
273 |
--------------------------------------------------------------------------------
/springmvc/assets/1536050065921.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1536050065921.png
--------------------------------------------------------------------------------
/springmvc/assets/1547948320307.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1547948320307.png
--------------------------------------------------------------------------------
/springmvc/assets/1547948554726.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1547948554726.png
--------------------------------------------------------------------------------
/springmvc/assets/1547948611496.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1547948611496.png
--------------------------------------------------------------------------------
/springmvc/assets/1547948632377.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1547948632377.png
--------------------------------------------------------------------------------
/springmvc/assets/1547948685468.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1547948685468.png
--------------------------------------------------------------------------------
/springmvc/assets/1547948785389.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1547948785389.png
--------------------------------------------------------------------------------
/springmvc/assets/1547948785390.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/1547948785390.png
--------------------------------------------------------------------------------
/springmvc/assets/Spring-mvc-framework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/Spring-mvc-framework.png
--------------------------------------------------------------------------------
/springmvc/assets/spring-overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/spring-overview.png
--------------------------------------------------------------------------------
/springmvc/assets/springmvc_核心架构图.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frank-lam/SpringMVC_MyBatis_Learning/0cbd2fad8a33201391a9e8e5151a6e96127e30e9/springmvc/assets/springmvc_核心架构图.jpg
--------------------------------------------------------------------------------