Maven Eclipse 整合SSM
新建工程选择webapp
创建目录结构
- src/main/java
- src/main/resources
- mappers
- XXXMapper.xml
- applicationContext.xml
- springmvc.xml
- sqlMapConfig.xml
- mappers
- src/main/webapp/WEB-INF
- jsp
- XXX. jsp
- web.xml
- jsp
- pom.xml
xml文件
- pom.xml 引入依赖和插件:Spring Springmvc Mybatis / JDBC相关:SQL驱动,连接池 / jackson Tomcat插件 jdk版本等等
- XXXMapper.xml sql语句在此拼接
- applicationContext.xml Mybatis 详细配置
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///ssmdb"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<!-- 整合MyBatis -->
<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:/sqlMapConfig.xml"></property>
<property name="mapperLocations" value="classpath:/mappers/*.xml"></property>
</bean>
<!-- MyBatis MapperBean扫描器,负责为MapperBean生成实现类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.zjn.mapper"></property>
</bean>
<!-- 声明式事务处理 -->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启注解方式控制事务 -->
<tx:annotation-driven/>
</beans>
- springmvc.xml 视图解析器
<!-- 配置包扫描 -->
<context:component-scan base-package="cn.zjn.controller"></context:component-scan>
<!-- 配置注解方式mvc -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
- sqlMapConfig.xml
- web.xml 监听器 前端控制器
<web-app>
<!-- 配置Spring启动的监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置SpringMVC的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
开发
- 控制层
- 服务层
- 持久层
- 配置run
MVC概念
Module:模型–封装数据
View:视图–展示数据
Controller:控制器
Spring MVC原理 — 请求驱动
- 客户端发出请求,请求提交到DispatcherServlet
- DispatcherServlet查询HandlerMapping,得到Handler路径
- HandlerAdapter调用真正的Handler处理请求
- Handler处理完成,返回ModelAndView对象给DispatcherServlet
- ViewResolver [resolve:解决(问题或困难); 决心],接收DispatcherServlet的ModelAndView,根据映射关系得到真正的view
- DispatchServlet中的Model数据嵌入到视图解析器解析之后的view
- 将最终的view返回给客户端,显示给用户
使用
前端控制器
- 配置前端控制器 在 web.xml
<web-app>
<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>*.action</url-pattern>
</servlet-mapping>
</web-app>
- 其他的bean
视图解析 ModelAndView
- 配置视图解析器 在 springmvc.xml
Spring MVC中所有控制器的处理器方法都要返回一个逻辑视图的名字。如下:如果返回一个叫example的逻辑视图名,视图解析器会将请求转发到/WEB-INF/jsp/example.jsp
视图去渲染。
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置包扫描 -->
<!--如果某个类的头上带有特定的注解
@Component,@Repository,@Service,@Controller,就会将这个对象作为Bean注册进Spring容器。-->
<context:component-scan base-package="查找指定包中的component组件"></context:component-scan>
<!-- 配置注解方式mvc -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
注解初识
- Controller
- RestController
- RequestMapping
- RequestBody
- ResponseBody
@RestController
- 使用了这个注解,不能返回jsp、html页面
- 使用了这个注解以后如果要返回json数据,那么就不需要加@ResponseBody注解
- 属于Spring MVC 不是Spring Boot特有的注解。
@RestController = @ResponseBody + @Controller
@Controller
@ResponseBody
public @interface RestController {
/**
The value may indicate a suggestion for a logical component name,
值可能表示一个逻辑组件名
to be turned into a Spring bean in case of an autodetected component.
被自动检测的组件被转化成Spring的bean
@return the suggested component name, if any
返回一个逻辑组件名 艹翻译不通
@since 4.0.1
*/
String value() default "";
}
@ResponseBody 与 @RequestBody
HttpMessageConverter
实现转换
https://blog.csdn.net/justry_deng/article/details/80972817
https://blog.csdn.net/ff906317011/article/details/78552426#commentBox
RequestBody – 接收请求体
- ajax传送json对象,@RequestBody接收json字符串
- 接收json字符串,反序列化→java对象
- 用来接收前端传递给后端的json字符串中的数据(请求实体中的数据)!!!请求体中的数据,即如果数据放到请求体中要有@RequestBody才能接收到
- 使用@RequestBody接收数据时,前端不能使用GET方式提交数据,要使用POST方式进行提交
- 一个请求只能有一个RequestBody
- json字符串中如果value是
""
,后端对应属性如果是String类型的,那么接受到的就是"",如果是后端属性的类型是Integer、Double等,那么接收到的就是null
RequestBody如何将json转化为java对象
BeanDeserializerBase
public abstract Object deserializeFromObject(JsonParser p, DeserializationContext ctxt)
throws IOException;
class BeanDeserializer extends BeanDeserializerBase
public class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable {
@Autowired
User bean = null;
protected BeanDeserializer(BeanDeserializerBase src) {
super(src);
// TODO Auto-generated constructor stub
}
@Override
public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException {
// 获取json字符串的key
String propName = p.getCurrentName();
do {
p.nextToken();
//查询模型中是否有对应属性的setter方法
SettableBeanProperty prop = _beanProperties.find(propName);
//如果有
if(prop != null) {
try {
//反序列化并且设置java对象
prop.deserializeAndSet(p, ctxt,bean);
} catch (Exception e) {
// TODO: handle exception
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
//如果没有
/* if (_ignorableProps != null && _ignorableProps.contains(propName)) {
//setter是空 忽略
handleIgnoredProperty(p, ctxt, bean, propName);
}
else if (_anySetter != null) {
//setter不是空 设置
try {
// should we consider return type of any setter?
_anySetter.deserializeAndSet(p, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
} else {
// Unknown: let's call handler method
handleUnknownProperty(p, ctxt, bean, propName);
}
*/
handleUnknownVanilla(p,ctxt,bean,propName);
//一次获取下一个key,重复逻辑,进而完成json到java对象的转换
}while((propName = p.nextFieldName())!=null);
return bean;
}
}
用法实例
在这里插入代码片
@ResponseBody
- 将控制器返回的对象转换为指定格式(json、xml),通过Response响应给客户端。
/**
* Annotation that indicates a method return value should be bound to the web
* response body. Supported for annotated handler methods in Servlet environments.
*
* <p>As of version 4.0 this annotation can also be added on the type level in
* which case it is inherited and does not need to be added on the method level.
*
* @author Arjen Poutsma
* @since 3.0
* @see RequestBody
* @see RestController
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService = null;
@ResponseBody
@RequestMapping("/pay.action")
public String pay(String orderId){
try{
orderService.payOrder(orderId);
return "1";
}catch (Exception e) {
e.printStackTrace();
return "0";
}
}
}
@RequestMapping
public @interface RequestMapping {
/**
* Assign(分配) a name to this mapping.
* with "#" as separator.
*/
String name() default "";
/**
* The primary mapping expressed by this annotation.
* <p>In a Servlet environment this is an alias for {@link #path}.
* For example {@code @RequestMapping("/foo")} is equivalent to
* {@code @RequestMapping(path="/foo")}.
*/
@AliasFor("path")
String[] value() default {};
/**
* In a Servlet environment only: the path mapping URIs (e.g. "/myPath.do").
* Ant-style path patterns are also supported (e.g. "/myPath/*.do").
* At the method level, relative paths (e.g. "edit.do") are supported within
* the primary mapping expressed at the type level. Path mapping URIs may
* contain placeholders(占位符) (e.g. "/${connect}")
*/
@AliasFor("value")
String[] path() default {};
/**
* The HTTP request methods to map to, narrowing the primary mapping:
* GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit(继承)
* this HTTP method restriction(限定,法规) (i.e. the type-level restriction
* gets checked before the handler method is even resolved).
*/
RequestMethod[] method() default {};
- URI模板
http://www.example.com/owners/{ownerId}
→http://www.example.com/owners/fred
URI模板"/owners/{ownerId}"
指定了一个变量,名为ownerId
。当控制器处理这个请求的时候,ownerId
的值就会被URI模板中对应部分的值所填充。比如说,如果请求的URI是/owners/fred
,此时变量ownerId的值就是fred. `
@RequestMapping(path="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}