Spring mvc学习笔记

springmvc学习笔记

需要配置两个bean,BeanNameUrlHandlerMapping,  SimpleControllerHandlerAdapter, 第一个是表示的请求映射的方式定义,比如还有一种是注解DefaultAnnotationHandlerMapping就是指在类或者方法的级别上,通过注解去描述http path的方式去映射Handler。第二种是指的所有实现了Controller接口的bean可以作为mvc中的处理器。
InternalResourceViewResolver是用来支持servlet,jsp的视图解析的。然后里面配置的property中,name=viewClass, value=JstlView是表示jsp页面中需要用到jstl标签库,因此jar包中需要有这个jstl的jar包。
2.5之后引入注解@Controller等,3.0引入restful架构风格支持,类似于@RequestBody, @ResponseBody等,还有JSP-303验证框架的支持,这个是通过注解去验证元数据@NumberFormat等。
@RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换);
@ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);
HttpMessageConverter:http输入输出转换器。
ContentNegotiatingViewResolver:内容协商视图解析器,就是解析器,知识它会根据请求信息将同一模式数据以不同的视图方式展示(json, xml, html), RESTful架构风格中很重要的概念(同一资源,多种表现形
式)。
Spring 3 引入 一个mvc XML的命名空间用于支持mvc配置,包括如:
<mvc:annotation-driven>:
--自动注册基于注解风格的处理器需要的DefaultAnnotationHandlerMapping、
AnnotationMethodHandlerAdapter
--支持Spring3的ConversionService自动注册
--支持JSR-303验证框架的自动探测并注册(只需把JSR-303实现放置到classpath)
--自动注册相应的HttpMessageConverter(用于支持@RequestBody 和 @ResponseBody)(如XML输入输出转
换器(只需将JAXP实现放置到classpath)、JSON输入输出转换器(只需将Jackson实现放置到classpath))等。

<mvc:default-servlet-handler>:当在web.xml 中DispatcherServlet使用<url-pattern>/</url-pattern> 映射
时,能映射静态资源(当Spring Web MVC框架没有处理请求对应的控制器时(如一些静态资源),转交给默认的
Servlet来响应静态文件,否则报404找不到资源错误,)。

新的@Contoller和@RequestMapping注解支持类:处理器映射RequestMappingHandlerMapping和处理器适配器
RequestMappingHandlerAdapter组合来代替Spring2.5开始的处理器映射DefaultAnnotationHandlerMapping和处
理器适配器AnnotationMethodHandlerAdapter。

DispatcherServlet默认使用WebApplicationContext作为上下文,spring默认配置文件是/WEB-INF/[servlet名字]-servlet.xml,
也可以通过contextConfigLocation去修改,
<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-name>classpath:spring-servlet-config.xml</param-name>
</init-param>

在web.xml里面配置ContextLoaderListener监听器,会监听spring上下文,
其实也可以不用配置这个,如果整个项目只用了springmvc这个框架,而不使用spring的配置的话,就可以不用配置这个,因为mvc的话本身就可以配置让容器去加载所有的bean,<context:component-scan base-package=""/>,可以扫描base-package里面所有类上的注解,@Controller, @Service, @Reponsitory等等。
配置这个监听器是为了更好的与其他web框架继承,它能够加载除web层的所有bean,如dao,service等。
http://www.cnblogs.com/baiduligang/p/4247164.html
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:spring-common-config.xml,
        classpath:spring-budget-config.xml
    </param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>



DispatcherServlet默认使类似于用的是WebApplicationContext作为上下文,这个上下文中会有一些默认加载的bean, 比如一些类似于DefaultAnnotationAdapter,LocalResolver这些bean,在容器启动的时候就已经初始化成功,如果本身已经在配置文件里面配置,则容器不会加载默认的配置,默认的配置在DispatcherServlet这个类的同目录下的DispatcherServlet.properties,这个文件里面配置的bean是as fallback when no matching beans are found in the DispatcherServlet context,即在上下文中找不到的时候的备用bean.

Controller的作用:(功能处理部分)收集、验证请求参数并绑定到命令对象上;将命令对象交给业务对象,由业务对象处理并返回模型数据;返回一个ModelAndView。
DispatcherServlet作用:(控制流程调度部分)负责将请求委托给控制器进行处理;根据控制器返回的ModelAndView选择具体的视图进行渲染。
因此,mvc模式中完整的c是由DispatcherServlet+Controller完成的。


强烈推荐: http://www.mnot.net/cache_docs/(中文版http://www.chedong.com/tech/cache_docs.html)详细了解HTTP缓存控制及为什么要缓存。

BaseCommandController:绑定参数到命令对象
AbstractCommandController:可以实现这个控制器来创建命令控制器
AbstractWizardFormController:向导控制器,提供多步骤的表单支持(如填写个人资料时分步骤填写基本信息,工作信息,学校信息等)
MultiActionController:支持在一个控制器是里面添加多个功能处理方法
///问题**************
1、MultiActionController如何将不同的请求映射不同的请求的功能处理方法呢?
    Spring Web MVC提供了MethodNameResolver(方法名解析器)用于解析当前请求到需要执行的功能处理方法的方
法名。默认使用InternalPathMethodNameResolver实现类,另外还提供了ParameterMethodNameResolver和
PropertiesMethodNameResolver,当然我们也可以自己来实现,稍候我们仔细研究下它们是如何工作的。
2、那我们的功能处理方法应该怎么写呢?
    public (ModelAndView | Map | String | void) actionName(HttpServletRequest request, HttpServletResponse
        response, [,HttpSession session] [,AnyObject]);

1)、返回值:即模型和视图部分;
    ModelAndView:模型和视图部分,之前已经见过了;
    Map:只返回模型数据,逻辑视图名会根据RequestToViewNameTranslator实现类来计算,稍候讨论;
    String:只返回逻辑视图名;
    void:表示该功能方法直接写出response响应(如果其他返回值类型(如Map)返回null则和void进行相同的处理);
2)、actionName:功能方法名字;由methodNameResolver根据请求信息解析功能方法名,通过反射调用;
3)、形参列表:顺序固定,“[]”表示可选, 比如如果第三个参数是session,最后一个只能是命令对象,不能先是命令对象,后是session。

? 匹配一个字符,如/index? 可以匹配 /index1 , 但不能匹配 /index 或 /index12
* 匹配零个或多个字符,如/index1/*,可以匹配/index1/demo,但不匹配/index1/demo/demo
** 匹配零个或多个路径,如/index2/**:可以匹配/index2路径下的所有子路径,如匹配/index2/demo,或/index2

URL,URI:URL是统一资源路径,URI是统一资源标识符。通过URL可以直接定位到一个资源,而URI只能认识这个资源,但不能找到这个资源,比如浏览器里面的网址就是URL,而项目中的/someproject/home,算是一种资源标识符,标识的是一个资源。URL算是一种具体的URI。


Chrome浏览器: ModHeader是添加请求头的一个扩展程序
安装路径:https://chrome.google.com/webstore/detail/idgpnmonknjnojddfkpgkljpfnnfcklj

媒体类型格式:type/subtype(;parameter)?
常见媒体类型:
text/html : HTML格式
text/plain :纯文本格式
text/xml :XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送
到服务器(表单默认的提交数据的格式)。
multipart/form-data : 当你需要在表单中进行文件上传时,就需要使用该格式
application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)。
在如tomcat服务器的 “conf/web.xml”中指定了扩展名到媒体类型的映射,在此我们可以看到服务器支持的媒体类
型。

Content-Type:内容类型,即请求/响应的内容区数据的媒体类型, 例Content-Type:application/x-www-form-urlencoded

consumes:消费者,即表示这个方法接收什么类型的数据,即request的数据类型
produces:生产者,即表示这个方法将生产哪种类型的数据,即response的数据类型

例:headers = "Accept=application/json"
Accept头:application/xml;q=0.5,application/json;q=0.9,text/html
将按照如下顺序进行produces的匹配 ①text/html ②application/json ③application/xml
q参数为媒体类型的质量因子,越大则优先权越高(从0到1)


窄化时是覆盖 而 非继承
如类级别的映射为@RequestMapping(value="/narrow", produces="text/html"),方法级别的为
@RequestMapping(produces="application/xml"),此时方法级别的映射将覆盖类级别的,因此请求头
“Accept:application/xml”是成功的,而“text/html”将报406错误码,表示不支持的请求媒体类型。


消费的数据,如JSON数据、XML数据都是由我们读取请求的InputStream并根据需要自己转换为相应的模型数据,比
较麻烦;
生产的数据,如JSON数据、XML数据都是由我们自己先把模型数据转换为json/xml等数据,然后输出响应流,也是比
较麻烦的。
Spring提供了一组注解(@RequestBody、@ResponseBody)和一组转换类(HttpMessageConverter)来完成我们遇
到的问题6.68
因此以后就可以直接使用@ResponseBody(produces="application/json")就会将数据转换为json类型输出了

@RequestPart:绑定“multipart/form-data”数据

前台获取数据的方式${xxx},是用的jstl.jar去支持的。

Spring Web MVC 提供Model、Map或ModelMap让我们能去暴露渲染视图需要的模型数据(这个跟命令对象不一样,这个是为了给前台去展示数据的,比如标志一类的)。
Springmvc中处理器的方法里面还有一种写法
public ModelAndView mergeModel(Model model){
    ModelAndView mav = new ModelAndView("success");
    mav.addObject("a", "update");
    model.addAttribute("a", "new");
    return mav;
}
其他写法public string test(request, response, user);public ModelAndView test(request, response, user);
视图页面的a将显示update,而不是new
因为ModelAndView会合并功能处理方法中的形式参数的数据, 但如果有同名,则会覆盖

@RequestParam注解主要有哪些参数:
value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,默认值可以是SpEL(Spring expression Language)表达式,如
“#{systemProperties['java.vm.version']}”。

如果请求中有多个同名的应该如何接收呢?如给用户授权时,可能授予多个权限,首先看下如下代码:
public String requestparam7(@RequestParam(value="role") String roleList)
如果请求参数类似于url?role=admin&rule=user,则实际roleList参数入参的数据为“admin,user”,即多个数据之间
使用“,”分割;我们应该使用如下方式来接收多个请求参数:
public String requestparam7(@RequestParam(value="role") String[] roleList)

public String requestparam8(@RequestParam(value="list") List<String> list)
到此@RequestParam我们就介绍完了.


1、@RequestParam绑定单个请求参数值;
2、@PathVariable绑定URI模板变量值;
3、@CookieValue绑定Cookie数据值
4、@RequestHeader绑定请求头数据;
5、@ModelValue绑定参数到命令对象;
6、@SessionAttributes绑定命令对象到session;
7、@RequestBody绑定请求的内容区数据并能进行自动类型转换等。
8、@RequestPart绑定“multipart/data”数据,除了能绑定@RequestParam能做到的请求参数外,还能绑定上传的
文件等。


@PathVariable绑定URI模板变量值
@RequestMapping(value="/users/{userId}/topics/{topicId}")
public String test(
    @PathVariable(value="userId") int userId,
    @PathVariable(value="topicId") int topicId)
    
    
@CookieValue绑定Cookie数据值
public String test(@CookieValue(value="JSESSIONID", defaultValue="") String sessionId)
如上配置将自动将JSESSIONID值入参到sessionId参数上,defaultValue表示Cookie中没有JSESSIONID时默认为空。


@RequestHeader绑定请求头数据
@RequestMapping(value="/header")
public String test(
    @RequestHeader("User-Agent") String userAgent,
    @RequestHeader(value="Accept") String[] accepts)

    
@ModelAttribute绑定请求参数到命令对象
①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定
流程,而且自动暴露为模型数据用于视图页面展示时使用;
②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对
象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到
模型对象中,用于视图页面展示时使用;
③暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为
模型数据,用于视图页面展示时使用。

一、
public String test1(@ModelAttribute("user") UserModel user)
    和6.6.1一节中的五、命令/表单对象功能一样。只是此处多了一个注解@ModelAttribute("user"),它的作用是将该绑
    定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用
    ${user.username}来获取绑定的命令对象的属性。

    
    
Spring的两个标签库:
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>


字段级别的解析/格式化
一、使用内置的注解进行字段级别的解析/格式化:
package cn.javass.chapter7.model;
public class FormatterModel {
    @NumberFormat(style=Style.NUMBER, pattern="#,###")
    private int totalCount;
    @NumberFormat(style=Style.PERCENT)
    private double discount;
    @NumberFormat(style=Style.CURRENCY)
    private double sumMoney;
    @DateTimeFormat(iso=ISO.DATE)
    private Date registerDate;
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date orderDate;
    //省略getter/setter
}
@Number:定义数字相关的解析/格式化元数据(通用样式、货币样式、百分数样式),参数如下:
    style:用于指定样式类型,包括三种:Style.NUMBER(通用样式) Style.CURRENCY(货币样式)
        Style.PERCENT(百分数样式),默认Style.NUMBER;
    pattern:自定义样式,如patter="#,###";
@DateTimeFormat:定义日期相关的解析/格式化元数据,参数如下:
    pattern:指定解析/格式化字段数据的模式,如”yyyy-MM-dd HH:mm:ss”
    iso:指定解析/格式化字段数据的ISO模式,包括四种:ISO.NONE(不使用) ISO.DATE(yyyy-MM-dd)
        ISO.TIME(hh:mm:ss.SSSZ) ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ),默认ISO.NONE;
    style:指定用于格式化的样式模式,默认“SS”,具体使用请参考Joda-Time类库的
        org.joda.time.format.DateTimeFormat的forStyle的javadoc;

优先级: pattern 大于 iso 大于style。




(个人记录下,有的观点或许会改,慎之)

获得datasource的方法:

需要注意:当在dao层使用SpringConnUtils去获得Connection的时候,应该使用注解的方式去拿到SpringConnUtils对象,否则在SpringConnUtils里面就不能拿到注解的datasource

@Repository
public class UsersDAO {
	
//	<span style="color:#ff6666;">private SpringConnUtils connectionUtils = new SpringConnUtils();</span>
	
	@Autowired
	private SpringConnUtils connectionUtils;
	
	public void addUserInfo(Users user) throws Exception{
		Connection conn = connectionUtils.getConnection();
		String sql = "insert into users(userid,username,password) values(?,?,?)";
		PreparedStatement pst = conn.prepareStatement(sql);
		conn.prepareStatement(sql);
		pst.setInt(1, user.getUserId());
		pst.setString(2, user.getUserName());
		pst.setString(3, user.getPassword());
		pst.executeUpdate();
		connectionUtils.closeConn(conn);
	}
}
@Repository
public class SpringConnUtils implements ConnectionUtils {

	@Autowired
	private DriverManagerDataSource dataSource;
	
	@Override
	public Connection getConnection() {
		Connection connection;
		if(dataSource == null){
			return null;
		}
		try {
			connection = dataSource.getConnection();
			return connection;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}


这里new一个对象的话, 里面的成员变量dataSource是null,所以获取不到connection,虽然dataSource用的注解,但是这里与new并不能混用,@auwried是按照类型去容器里面查找对应的实例,而new是另外一个对象,这里有依赖注入的特点。如果有不对的,请指出,不胜感激



 [S1]New一个对象的时候注入的东西是不是没有用

使用配置文件的方式去配置数据源

<!-- datasource -->
	<context:property-placeholder location="/WEB-INF/jdbc.properties" />
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${driver}"></property>
		<property name="url" value="${url}"></property>
		<property name="username" value="${name}"></property>
		<property name="password" value="${password}"></property>
	</bean>

location这里的配置文件如果没有在class里面,则不需要写classpath


注意事项

1)       <mvc:annotation-driven /> 这个配置会自动注册AnnotationMethodHandlerAdapter和DefaultAnnotationHandlerMapping两个bean

2)       <context:component-scanbase-package="com.fen" />配置跟<context:annotation-config/>这个是重复的,第一个包含第二个,扫描的时候就已经开启


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值