Spring 04 MVC

Maven Eclipse 整合SSM

新建工程选择webapp
创建目录结构
  • src/main/java
  • src/main/resources
    • mappers
      • XXXMapper.xml
    • applicationContext.xml
    • springmvc.xml
    • sqlMapConfig.xml
  • src/main/webapp/WEB-INF
    • jsp
      • XXX. jsp
    • web.xml
  • 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原理 — 请求驱动

  1. 客户端发出请求,请求提交到DispatcherServlet
  2. DispatcherServlet查询HandlerMapping,得到Handler路径
  3. HandlerAdapter调用真正的Handler处理请求
  4. Handler处理完成,返回ModelAndView对象给DispatcherServlet
  5. ViewResolver [resolve:解决(问题或困难); 决心],接收DispatcherServlet的ModelAndView,根据映射关系得到真正的view
  6. DispatchServlet中的Model数据嵌入到视图解析器解析之后的view
  7. 将最终的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

@AliasFor注解

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";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值