- 浏览: 31742 次
- 性别:
- 来自: 杭州
最新评论
-
www19940501a:
我想问如果在2的基础上,把内部类的static修饰符去除,还会 ...
ThreadLocal与内存回收 -
yingjianxuehun:
为啥我下载的Spring3.x下载下来都是xx..RELEAS ...
Spring源码阅读1---导入eclipse -
贾懂凯:
...
ThreadLocal与内存回收 -
zys0523:
wangling1hao 写道你确定用的spring3.1.1 ...
Spring源码阅读1---导入eclipse -
wangling1hao:
你确定用的spring3.1.1么?为啥我用的spring3. ...
Spring源码阅读1---导入eclipse
SpringMVC最近大有赶超struts2的趋势。
乘着在学校有空对该框架做一定的熟悉和了解,争取毕业设计用这个框架完成
第一部建立一个web项目
maven构建语句,构建出一个空的web项目
mvn archetype:create -DgroupId=packageName -DartifactId=webappName -DarchetypeArtifactId=maven-archetype-webapp -Dwtpversion=1.0
接着在pom中加入spring MVC的依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.springframework.mvc</groupId> <artifactId>mvc</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>mvc Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <java-version>1.6</java-version> <org.springframework-version>3.1.0.RELEASE</org.springframework-version> <org.aspectj-version>1.6.10</org.aspectj-version> <org.slf4j-version>1.6.1</org.slf4j-version> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> <exclusions> <!-- Exclude Commons Logging in favor of SLF4j --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework-version}</version> </dependency> <!-- AspectJ --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${org.aspectj-version}</version> </dependency> <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${org.slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> <scope>runtime</scope> </dependency> <!-- @Inject --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>1.2</version> </dependency> <!-- Jackson JSON Processor --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.8.1</version> </dependency> <!-- Rome Atom+RSS --> <dependency> <groupId>net.java.dev.rome</groupId> <artifactId>rome</artifactId> <version>1.0.0</version> </dependency> <!-- JSR 303 with Hibernate Validator --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.0.0.GA</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.1.0.Final</version> </dependency> <!-- Joda Time Library --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>1.6.2</version> </dependency> <!-- File Upload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.0.1</version> </dependency> <!-- Test --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> </dependencies> <repositories> <!-- For testing against latest Spring snapshots --> <repository> <id>org.springframework.maven.snapshot</id> <name>Spring Maven Snapshot Repository</name> <url>http://maven.springframework.org/snapshot</url> <releases><enabled>false</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </repository> <!-- For developing against latest Spring milestones --> <repository> <id>org.springframework.maven.milestone</id> <name>Spring Maven Milestone Repository</name> <url>http://maven.springframework.org/milestone</url> <snapshots><enabled>false</enabled></snapshots> </repository> </repositories> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>${java-version}</source> <target>${java-version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>install</id> <phase>install</phase> <goals> <goal>sources</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <!-- Have to use version 1.2 since version 1.3 does not appear to work with ITDs --> <version>1.2</version> <dependencies> <!-- You must use Maven 2.0.9 or above or these are ignored (see MNG-2972) --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${org.aspectj-version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>${org.aspectj-version}</version> </dependency> </dependencies> <executions> <execution> <goals> <goal>compile</goal> <goal>test-compile</goal> </goals> </execution> </executions> <configuration> <outxml>true</outxml> <source>${java-version}</source> <target>${java-version}</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.1</version> </plugin> </plugins> </build> </project>
这样我们的依赖已经配置齐全了,接下来就是配置前端控制器FrontController在SpringMVC中是DispatcherServlet
他位于org.springframework.web.servlet.DispatcherServlet
在web.xml中配置
<!-- 处理所有请求 process all request --> <servlet> <servlet-name>FrontController</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> //会反射注入 <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>FrontController</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
我们看一下init-param为什么必须得叫做contextConfigLocation
首先看DispatcherServlet的构造方法
public DispatcherServlet() { super(); }
查看父类发现有setContextConfigLocation方法
/** * Set the context config location explicitly, instead of relying on the default * location built from the namespace. This location string can consist of * multiple locations separated by any number of commas and spaces. */ public void setContextConfigLocation(String contextConfigLocation) { this.contextConfigLocation = contextConfigLocation; }
查看是谁调用了这个方法
没人调用这个方法,那么假定这个方法是被反射调用的
再往父类上查找,可以在setContextConfigLocation处加一个断点,debug的时候就能看到是如何被调用的
/** * Map config parameters onto bean properties of this servlet, and * invoke subclass initialization. * @throws ServletException if bean properties are invalid (or required * properties are missing), or if subclass initialization fails. */ @Override public final void init() throws ServletException { if (logger.isDebugEnabled()) { logger.debug("Initializing servlet '" + getServletName() + "'"); } // Set bean properties from init parameters. try { //获得所有的属性值 PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment)); initBeanWrapper(bw); bw.setPropertyValues(pvs, true); } catch (BeansException ex) { logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex); throw ex; } // Let subclasses do whatever initialization they like. initServletBean(); if (logger.isDebugEnabled()) { logger.debug("Servlet '" + getServletName() + "' configured successfully"); } }
通过AbstractPropertyAccessor往里面填充属性
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException { List<PropertyAccessException> propertyAccessExceptions = null; List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ? ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues())); for (PropertyValue pv : propertyValues) { try { // This method may throw any BeansException, which won't be caught // here, if there is a critical failure such as no matching field. // We can attempt to deal only with less serious exceptions. //往里面填充属性的核心方法 setPropertyValue(pv); } catch (NotWritablePropertyException ex) { if (!ignoreUnknown) { throw ex; } // Otherwise, just ignore it and continue... } catch (NullValueInNestedPathException ex) { if (!ignoreInvalid) { throw ex; } // Otherwise, just ignore it and continue... } catch (PropertyAccessException ex) { if (propertyAccessExceptions == null) { propertyAccessExceptions = new LinkedList<PropertyAccessException>(); } propertyAccessExceptions.add(ex); } } // If we encountered individual exceptions, throw the composite exception. if (propertyAccessExceptions != null) { PropertyAccessException[] paeArray = propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]); throw new PropertyBatchUpdateException(paeArray); } }
可以看到在BeanWrapperImp当中实现了setPropertyValue(String propertyName, Object value)方法
public void setPropertyValue(String propertyName, Object value) throws BeansException {
BeanWrapperImpl nestedBw;
try {
nestedBw = getBeanWrapperForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
}
PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
nestedBw.setPropertyValue(tokens, new PropertyValue(propertyName, value));
}
可以看到这里的确是反射调用的.
这样就完成了springMVC资源的载入
看下之前载入的资源文件做了什么
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- 开启注解 --> <annotation-driven /> <!-- 引入用户定义的@Controller 用来处理请求 --> <beans:import resource="controllers.xml" /> </beans:beans>
再看一下controllers.xml
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 自动扫描组件 --> <context:component-scan base-package="com.springframework.helloworld" /> </beans>
包扫描把所有有@controller注解的类spring会对其进行加载
@Controller //注解表示自己是controller public class SimpleController { //对应映射的路径 这里就表示 http://localhost/项目名/simple会映射到该控制器 @RequestMapping("/simple") //@ResponseBody表示这个返回的string将会当成输出值返回给浏览器 public @ResponseBody String simple() { return "hello world!"; } }
所有的处理完毕~ 放入tomcat第一个springMVC的Helloworld就诞生啦~
相关推荐
通过这个HelloWorld程序,你可以学习到如何配置SpringMVC环境,编写简单的控制器,以及如何使用视图解析来展示结果。实践操作是理解框架的最佳方式,尝试运行并分析`TestSpringMVC`项目,将有助于你深入理解...
7. **测试**:运行项目,测试HelloWorld和登录功能,确保所有组件正常工作。 这个示例中的"SH"可能代表Spring和Hibernate的整合,具体实现可能包括"SH-config.xml"(Spring配置文件)、"SH-hibernate.cfg.xml"...
在`messages.properties`文件中,键值对的格式为`key=value`,例如`hello=Hello World!`。对于其他语言的文件,键保持不变,但值会根据对应的语言进行翻译。例如,在`messages_zh_CN.properties`中,`hello=你好,...
1. Hello World示例,展示SpringMVC的基本配置和请求处理。 2. 数据库连接与配置,演示如何通过Hibernate4连接MySQL并执行基本操作。 3. CRUD操作,通过Ajax实现前后端数据同步,无需页面刷新。 4. 分页和排序,利用...
return ResponseEntity.ok("{\"message\":\"Hello, Asynchronous World!\"}"); } } ``` 在这个例子中,`/asyncData`接口会异步地返回一个JSON字符串。`@Async`注解表明`asyncJson`方法将在后台线程中执行,`@...
在这个"springmvc国际化demo"中,我们将探讨如何实现Web应用的国际化,让应用能够支持多种语言环境,提升用户体验。国际化(i18n)是软件设计的一个重要方面,它允许程序根据用户的地区或语言设置来显示相应的文本...
${message}">Hello, World! ``` 这里,`th:text`指令会根据模型中的`message`属性显示相应语言的消息。 通过以上步骤,我们就实现了Spring MVC的国际化功能。这个过程中,源码的使用体现在自定义的Controller和...
《SpringMVC 入门与深入探索:从零开始到实战精通》 SpringMVC,作为Spring框架的重要组成...从简单的Hello World到复杂的业务场景,SpringMVC都能为我们提供强大且灵活的支持,助力我们在Web开发的道路上不断进步。
在这个基础实例中,我们将探讨如何使用Spring MVC的核心组件,如`@RequestMapping`和`@Controller`注解,来创建一个简单的"Hello, World!"应用,以深入理解其工作原理。 首先,我们需要在项目中引入Spring MVC的...
#### HelloWorld(SEUG) - **概述**:通过一个简单的示例介绍Dorado7的基本用法。 - **主要内容**:从创建项目到运行第一个示例的全过程。 #### Http请求的异常处理(草稿)(SEUG) - **概述**:指导如何处理HTTP...
1. **创建Maven工程**:创建一个名为"springboot-helloworld"的Jar工程。 2. **引入依赖**:在pom.xml文件中引入`spring-boot-starter-parent`作为父POM,它提供了依赖管理,简化了版本控制。再引入`spring-boot-...
第1章 Spring Boot 简介 讲解Spring Boot的项目背景,已经与其他技术框架(比如,Spring、SpringMVC、SpringCloud等)的关系。简单介绍下Spring Boot 整个生态系统 ...第3章 一个Hello World项目 本章是正式开始
- 在 Flex 中,HelloWorld 示例涉及创建一个简单的用户界面,并显示文本 "Hello World"。 - 这个示例帮助开发者熟悉 Flex 的基本语法和布局。 ### 4. 可视化页面组件 - **Flex 提供了丰富的组件库**,如按钮、...
hello.message=Hello, World! ``` 在`messages_zh_CN.properties`中: ```properties hello.message=你好,世界! ``` 现在,当用户访问应用时,Spring MVC会自动检测并设置locale,从相应的资源文件中加载对应的...
return "hello world!"; } public static void main(String[] args) { SpringApplication.run(HelloApplication.class, args); } } ``` 方式二: ``` @Controller @EnableAutoConfiguration public class ...
out.println("<h1>Hello, World!</h1>"); } } ``` **在Web工程中的整合应用** 在"JSP_JavaBean_Servlet"工程中,这三个技术通常协同工作。Servlet处理HTTP请求,根据需要创建或获取JavaBean实例,填充数据。然后...
model.addAttribute("name", "World"); return "hello"; } ``` 这里的"hello"就是Thymeleaf模板的名称,Thymeleaf会在templates目录下查找对应的hello.html文件,并将Model中的数据绑定到模板变量。 Thymeleaf还...
4. **快速开发第一个Spring Boot项目**:创建一个简单的Hello World应用,当浏览器发送"hello"请求时,服务器返回"Hello World"字符串。首先,使用Maven创建一个新的工程,利用Spring Initializr快速生成项目结构。...
依照惯例,会先编写一个最简单的Hello World程序。从项目配置,应用的编写,再到测试用例,最后运行项目。方面学员了解整个编码的流程。 第4章 开发环境的搭建 为了让实战过程更顺利,避免不要的问题,这里会先将...
依照惯例,会先编写一个最简单的Hello World程序。从项目配置,应用的编写, 再到测试用例,最后运行项目。方面学员了解整个编码的流程。 第4章 开发环境的搭建 为了让实战过程更顺利,避免不要的问题,这里会先...