搜索词>>jsp 耗时0.0080
  • Spring Boot中使用jsp视图模板-Java编程之

    Java编程之Spring Boot中使用jsp视图模板<h2>本文简介</h2> 本文将学习怎么创建spring boot项目并在spring boot项目中使用JSP模板作为视图层。这里会使用嵌入的tomcat server去运行这个程序。 <h2>一、项目结构图</h2> <img alt="项目结构图" class="img-thumbnail" src="/resources/assist/images/blog/76c1ff4b065246e3aac10181ea66430e.png" /> <h2>二、maven依赖文件pom.xml</h2> 这个应用将会使用以下依赖: <pre> <code class="language-xml"><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.howtodoinjava</groupId> <artifactId>spring-boot-demo</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-demo Maven Webapp</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Tomcat Embed --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <!-- To compile JSP files --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> </dependencies> </project></code></pre> <h2>三、spring boot应用的初始类</h2>   首先创建一个可部署的war文件的第一步是提供一个SpringBootServletInitializer子类和覆盖其配置()方法。这将使用Spring Framework的Servlet 3.0支持,并允许您在Servlet容器启动时配置您的应用程序。 <pre> <code class="language-java">import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; @SpringBootApplication public class SpringBootWebApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringBootWebApplication.class); } public static void main(String[] args) throws Exception { SpringApplication.run(SpringBootWebApplication.class, args); } }</code></pre> <h2><br /> 四、Spring Controller</h2> 控制器类可以将方法映射到应用程序中的特定url。在给定的应用程序中,它有两个视图,“/”和“/next” <pre> <code class="language-java">import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class IndexController { @RequestMapping("/") public String home(Map<String, Object> model) { model.put("message", "HowToDoInJava Reader !!"); return "index"; } @RequestMapping("/next") public String next(Map<String, Object> model) { model.put("message", "You are in new page !!"); return "next"; } }</code></pre> <h2>五、配置JSP视图解析器</h2> 解析jsp文件有两种方法可行<br /> 5.1在application.properties中添加以下内容:<br />   <pre> <code>spring.mvc.view.prefix=/WEB-INF/view/ spring.mvc.view.suffix=.jsp //For detailed logging during development logging.level.org.springframework=TRACE logging.level.com=TRACE</code></pre> <br /> 5.2配置InternalResourceViewResolver <pre> <code class="language-java">import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @EnableWebMvc @ComponentScan public class MvcConfiguration extends WebMvcConfigurerAdapter { @Override public void configureViewResolvers(ViewResolverRegistry registry) { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/view/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); registry.viewResolver(resolver); } }</code></pre> <h2><br /> 六、JSP文件编写</h2> <strong>index.jsp</strong> <pre> <code class="language-html"><!DOCTYPE html> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <html lang="en"> <body> <div> <div> <h1>Spring Boot JSP Example</h1> <h2>Hello ${message}</h2> Click on this <strong><a href="next">link</a></strong> to visit another page. </div> </div> </body> </html></code></pre> <strong>next.jsp</strong> <pre> <code class="language-html"><!DOCTYPE html> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <html lang="en"> <body> <div> <div> <h1>Another page</h1> <h2>Hello ${message}</h2> Click on this <strong><a href="/">link</a></strong> to visit previous page. </div> </div> </body> </html></code></pre> <h2>七、运行程序</h2> 在将整个代码编写并放置在文件夹中之后,通过在<code>SpringBootWebApplication</code> 类中执行main()方法来运行应用程序<br /> <br /> 打开浏览器:http://localhost:8080/<br /> <img alt="index" class="img-thumbnail" src="/resources/assist/images/blog/d961b6f45c7142039956ab5b0c411468.png" /><br /> 点击next<br /> <img alt="next" class="img-thumbnail" src="/resources/assist/images/blog/9d25d5a067434b51bb11015b822cce28.png" /> <h2>八、例子下载</h2> <a href="http://howtodoinjava.com/wp-content/downloads/spring-boot-demo-jsp-example.zip" rel="external nofollow" target="_blank">点击下载</a>
  • jsp中/el表达式中将后台传来的时间戳格式化为年月日时分秒

    jsp中/el表达式中将后台传来的时间戳格式化为年月日时分秒jsp中/el表达式中将后台传来的时间戳格式化为年月日时分秒<br /> 1.引入相关标签库 <pre> <code class="language-java"><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %></code></pre> <br /> 2.在jsp中执行执行者住转转换 <pre> <code class="language-xml"><jsp:useBean id="Timestamp" class="java.util.Date"/>  <c:set target="${Timestamp}" property="time" value="${obj.timestamp}"/>  <fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${Timestamp}" type="both"/> </code></pre> 说明:<br /> 1.定义一个date类型时间戳对象Timestamp<br /> 2.将后台传递过来的obj.timstamp转换为date类型的刚才创建的Timestamp对象<br /> 3.利用fmt标签将date对象进行格式化输出
  • jsp页面无法识别el表达式的解决方案

    jsp页面无法识别el表达式的解决方案,今天在写一个springmvc的小demo时,碰到一个问题,在jsp页面中书写为user.username的表达式语言,在浏览器页面中仍然显示为{user.username},说明jsp根本不认识${}标签,摸索了一下,发现我的web.xml中声明的是一、问题描述今天在写一个springmvc的小demo时,碰到一个问题,在jsp页面中书写为user.username的表达式语言,在浏览器页面中仍然显示为user.username的表达式语言,在浏览器页面中仍然显示为{user.username},说明jsp根本不认识${}标签,摸索了一下,发现我的web.xml中声明的是<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >​​​​​​​代码段 小部件
  • jsp利用el表达式切割字符串

    1.引入相关el表达式标签库 <pre> <code class="language-html"><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %></code></pre> 2.使用方法 <pre> <code class="language-html"><c:if test="${!empty obj.tags }"> <c:set value="${ fn:split(obj.tags, ',')}" var="tags" /> <c:forEach items="${tags}" var="tag"> <span>${tag}</span> </c:forEach> </c:if></code></pre> <br /> 说明:<br /> ${obj.tags} tags是obj对象的一个属性,以逗号分隔<br />  
  • jsp中EL表达式获取值中含逆转字符的处理

    jsp中EL表达式获取值中含逆转字符的处理<br /> <br /> 当我们在jsp页面使用EL表达式对input设置value的时候 <pre> <code class="language-html"><input type='text' value='${user.memo}'></code></pre> <strong><em>当${user.memo}的值中包含有单引号'的时候,就会因与外面的单引号冲突出错</em></strong><br /> 这时候我们需要逆转一下,这里提供<strong><em>两种解决的办法:</em></strong><br /> 方法1.采用<c:out></c:out><br /> 导入相关包: <pre> <code class="language-html"><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <input type='text' value='<c:out value="${user.name}" escapeXml="true"></c:out>'> </code></pre> 方法2.采用${fn:escapeXml(value)}<br /> 导入相关包 <pre> <code class="language-html"><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <input type='text' value='${fn:escapeXml(user.memo)}'> </code></pre>  
  • Spring MVC 5.0

    Spring框架5.0,spring mvc 5.0入门教程。DispatcherServlet的详细讲解配置以及spring mvc5.0的helloword程序<h2>引言</h2>   在本教程中,我们将学习Spring DispatcherServlet类,其职责以及如何使用示例进行配置。spring mvc 5.0基于Java配置 <h2>一.DispatcherServlet是什么</h2> <br />     <code>DispatcherServlet</code> 充当基于Spring的Web应用程序的前端控制器。 它提供了一个请求处理机制,其中实际工作由可配置的委托组件执行。 它从javax.servlet.http.HttpServlet继承,通常在web.xml文件中配置。<br /> <br />     Web应用程序可以定义任意数量的<code>DispatcherServlet</code> 实例。 每个servlet将在其自己的名称空间中运行,使用映射,处理程序等加载它自己的应用程序上下文。只有由ContextLoaderListener加载的根应用程序上下文(如果有)将被共享。 在大多数情况下,应用程序只有一个具有上下文根URL(/)的<code>DispatcherServlet</code> ,也就是说,到达该域的所有请求都将由它处理。<br /> <br />     <code>DispatcherServlet</code> 使用Spring配置类来发现它需要的委托组件,用于请求映射,视图解析,异常处理等。 <h2>二.DispatcherServlet它如何使用WebApplicationContext</h2>     在基于Spring的应用程序中,我们的应用程序对象位于一个对象容器中。 该容器在对象之间创建对象和关联,并管理其完整的生命周期。 这些容器对象被称为Spring管理的bean(或者简单的bean),在Spring世界中容器被称为应用程序上下文(通过类ApplicationContext)。<br /> <br />     WebApplicationContext是一个普通的ApplicationContext的扩展。 它是Web感知的ApplicationContext,即它具有Servlet上下文信息。 当DispatcherServlet被加载时,它查找WebApplicationContext的bean配置文件并初始化它。<br /> <br />     通过访问Servlet上下文,任何实现了ServletConextAware接口的spring bean都可以访问ServletContext实例,并且可以做很多事情。 例如,它可以获取上下文初始化参数,获取上下文根信息并获取Web应用程序文件夹中的资源位置。 <h2>三.基于XML配置的DispatcherServlet(作为参考理解主讲基于Java配置)</h2> 我们来看看典型的DispatcherServlet声明和初始化是怎样的。 <pre> <code class="language-xml"><web-app> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet-context.xml</param-value> </context-param> <servlet> <servlet-name>dispatcher-servlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher-servlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app></code></pre> 在上面的代码中,dispatcher-servlet-context.xml文件将包含所有可用于DispatcherServlet的bean定义和关联。 这些bean定义将覆盖在全局范围内使用相同名称定义的任何bean的定义。 例如: <pre> <code class="language-xml"><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="prefix"> <value>/WEB-INF/views/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans></code></pre> <h2>四.基于JAVA代码配置的DispatcherServlet </h2> 从Servlet 3.0开始,除了web.xml文件中的声明式配置,DispatcherServlet可以通过实现或扩展Spring提供的这三个支持类来编程配置  <ul> <li>WebAppInitializer接口</li> <li>AbstractDispatcherServletInitializer抽象类</li> <li>AbstractAnnotationConfigDispatcherServletInitializer抽象类</li> </ul> 在下面的类中,WebApplicationInitializer确保ApplicationSerializer类被SpringServletContainerInitializer(它本身自动引导)检测到并用来初始化任何Servlet 3容器。<br /> <br /> 引入spring mvc 5.0需要的相关依赖,pom.xml: <pre> <code class="language-xml"><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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.leftso.project.demo</groupId> <artifactId>demo-spring5-springmvc5</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <failOnMissingWebXml>false</failOnMissingWebXml> <spring.version>5.0.1.RELEASE</spring.version> <jstl.version>1.2.1</jstl.version> <tld.version>1.1.2</tld.version> <servlets.version>3.1.0</servlets.version> <jsp.version>2.3.1</jsp.version> </properties> <dependencies> <!-- Spring MVC Dependency --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- JSTL Dependency --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>${tld.version}</version> </dependency> <!-- Servlet Dependency --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlets.version}</version> <scope>provided</scope> </dependency> <!-- JSP Dependency --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>${jsp.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <sourceDirectory>src/main/java</sourceDirectory> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <path>/</path> </configuration> </plugin> </plugins> </build> </project></code></pre> <br /> <br /> 通过Java的方式可以将上面的web.xml写一个配置类: <pre> <code class="language-java">public class ApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { XmlWebApplicationContext appContext = new XmlWebApplicationContext(); appContext.setConfigLocation("/WEB-INF/dispatcher-servlet-context.xml"); ServletRegistration.Dynamic registration = servletContext .addServlet("rootDispatcher", new DispatcherServlet(appContext)); registration.setLoadOnStartup(1); registration.addMapping("/"); } }</code></pre> 基于Java 配置的完整配置<br /> <strong>例子一:</strong> <pre> <code class="language-java">package com.leftso.project.demo.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class ApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { // 创建 Spring ROOT context AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(AppConfig.class); // 管理ROOT context生命周期 servletContext.addListener(new ContextLoaderListener(rootContext)); // 创建spring的dispatcher ,servlet's Spring application context AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); dispatcherContext.register(DispatcherConfig.class); ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } } </code></pre> 在上面的代码中,<code>AppConfig</code> 和<code>DispatcherConfig</code> 类定义了将在Web应用程序上下文中的spring管理的bean。<br /> AppConfig: <pre> <code class="language-java">package com.leftso.project.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.leftso.project.demo.TestService; @Configuration @ComponentScan(basePackages = { "com.leftso" }) public class AppConfig { // 该类主要是spring 父级容器配置,里面可以定义很多的bean就像在spring-context.xml中一样 // 例如: @Bean public TestService testService() { return new TestService(); } } </code></pre> DispatcherConfig: <pre> <code class="language-java">package com.leftso.project.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration public class DispatcherConfig extends WebMvcConfigurationSupport { // 覆盖父类的配置进行spring mvc的其他详细配置,配置内容可参考xml的spring-mvc /** * * <pre> * [Function]: * JSP 视图解析器 * [Description]: * JSP 视图解析器 * </pre> * * @return JSP 视图解析器 */ @Bean public ViewResolver jspViewResolver() { InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); internalResourceViewResolver.setViewClass(JstlView.class); internalResourceViewResolver.setSuffix(".jsp"); internalResourceViewResolver.setPrefix("/WEB-INF/views/"); internalResourceViewResolver.setOrder(4); return internalResourceViewResolver; } /** * 资源文件处理器 */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); } } </code></pre> <p><strong>例子二:</strong><br /> 基于Java配置的Spring MVC 5.0的配置,spring mvc 5.0为我们提供了一个封装的抽象类,我们实现这个类并指定相关的配置Java就可以了非常方便:</p> <pre> <code class="language-java">package com.leftso.project.demo.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; /** * Spring MVC 5启动配置 * * @author xqlee * */ public class SpringMVC5AnnotationConfigDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] {}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebMvcConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } } </code></pre> <p>WebMvcConfig:<br />  </p> <pre> <code class="language-java">package com.leftso.project.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @EnableWebMvc @ComponentScan(basePackages = { "com.leftso.project.demo" }) public class WebMvcConfig implements WebMvcConfigurer { @Bean public InternalResourceViewResolver resolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; } } </code></pre> <p>这比起第一种方式少些几句代码。</p> <h2><br /> 五.编写一个测试spring mvc 5.0的controller</h2> <pre> <code class="language-java">package com.leftso.project.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @GetMapping("/sayHello.do") public Object sayHello(String name) { return "Hello," + name; } } </code></pre> 将项目添加到tomcat中,启动tomcat,并在浏览器中访问controller的地址:<br /> <img alt="spring mvc 5.0" class="img-thumbnail" src="/resources/assist/images/blog/e2422615e7924625a55ad38461e09529.png" /><br /> 从上图可以看到我们的<a rel="" target="_blank"href="http://www.leftso.com/blog/305.html" rel="" target="_blank">spring mvc5.0</a>项目已经成功启动.后续将讲解整合其他配置<br />  
  • java编程为啥会出现spring框架

    java编程为啥会出现spring框架,为什么要有Spring?<h2><strong>一、知史可以明鉴</strong></h2> <p>    我们学习技术的时代赶上了最好的时代,跳过了很多前人经常踩的坑,前人在踩坑的过程中总结了很多经验和教训,而新时代的我们只是继承了前人的经验和教训,而忽略了这些采坑的过程,以至于我们面对很多新技术都不知道他是什么?他为什么存在?他为什么可以解决这个问题?更不知道如何掌握其原理!云里雾里一头雾水!</p> <p>    交流群的很多小伙伴,常常私聊我让我推荐一下学习SSM框架的视频和资料,我首先会打开他的资料卡看一下他的年龄,如果超过了他这个年龄应有的水平,我就会问他JSP+Servlet学了吗?很多小伙伴的回答是简单的学了一下,然后,我会给他一个关于JSP+Servlet的实战项目,顺便给他们找一些SSM的项目,并且建议他们首先看这个JSP+Servlet的实战项目。</p> <p>    更有甚者,学了基础之后就开始学习Spring Boot的,当问他们Spring Boot是什么的时候,大致也可以回答出来“约定大于配置”,“用起来很简单”,但是在细究其原理,也是吱吱呜呜,一知半解!如果我们没有经历过Spring最开始繁琐的配置、然后一步步精简,根本体会不到为什么会有Spring Boot这个东西!<br /> <br />     不先学习常见的设计模式直接看Spring、MyBatis等源码,简直就是一个找虐的过程!不掌握Servlet原理、基本的Tomcat容器技术上来就看Spring MVC源码同样也是一个打击自信心的好地方!<br /> <br />  </p> <p>    学习是一个循序渐进的过程,不能急于求成,但也不能过分钻牛角尖!不能再一个技术上停滞不前,也不能如”蜻蜓点水”一般了了掠过!同样,如果你还没有掌握好Servlet和简单的设计模式我建议你先去查阅相关的资料进行系统的学习。</p> <p>    我也相信很多图书或视频等资料都忽略了讲述为什么会有Spring的过程,要么是简单概括并且痛斥EJB的各种弊端,要么就是只字不提,这是一种对读者很不负责任的表现,知史可以明鉴!因此,在进一步学习Spring核心原理之前,我们有必要介绍一下整个Web发展的简单历史,一步步引出为什么会有Spring!<br /> <br />  </p> <h2><strong>二、Web发展简史</strong></h2> <p>老一辈的软件开发人员一般经历了从Model1到Model2,然后到后来的三层模型,最后到现在的Spring Boot。如果从Model1到Model2说起到我们现在使用的Spring Boot为整个时间轴的话,大致可以分为4个阶段:</p> <p>(1)初级阶段:使用Model1/Model2/三层模模型进行开发;</p> <p>(2)中级阶段:使用EJB进行分布式应用开发,忍受重量级框架带来的种种麻烦;</p> <p>(3)高级阶段:使用Spring春天带给我们的美好,但是还要忍受很多繁琐的配置;</p> <p>(4)骨灰级阶段:使用Spring Boot,畅享“预定大于配置”带给我们的种种乐趣!<br /> <br />  </p> <h2><strong>三、Web发展初级阶段</strong></h2> <p><strong>1、Model1开发模式:</strong></p> <p>Model1的开发模式是:JSP+JavaBean的模式,它的核心是Jsp页面,在这个页面中,Jsp页面负责整合页面和JavaBean(业务逻辑),而且渲染页面,它的基本流程如下:<br /> <img alt="java servlet请求流程" class="img-thumbnail" src="/resources/assist/images/blog/246977dbac84441fa007ecf15d4b8362.png" /><br />  </p> <p>    相信很多小伙伴在刚学习Web的时候,肯定使用到了Model1开发模式,也就是我们的业务代码、持久化代码直接写在Jsp页面里边,使用Jsp直接处理Web浏览器的请求,并使用JavaBean处理业务逻辑。</p> <p>    利用我们现在熟悉的MVC模型的思想去看,虽然编写代码十分容易,但Jsp混淆了MVC模型中的视图层和控制层,高度耦合的结果是Jsp代码十分复杂,后期维护困难!<br />  </p> <p><strong>2、Model2开发模式:</strong></p> <p>  Model1虽然在一定程度上解耦了,但JSP依旧即要负责页面控制,又要负责逻辑处理,职责不单一!此时Model2应运而生,使得各个部分各司其职,Model2是基于MVC模式的。</p> <p>  Model2的开发模式是:Jsp+Servlet+JavaBean的模式,它和Model1不同的是,增加了Servlet,将调用页面数据,调用业务逻辑等工作放到了Servlet中处理,从而减轻了Jsp的工作负担!它的基本流程如下:<br /> <img alt="servlet web流程图" class="img-thumbnail" src="/resources/assist/images/blog/2ac48ef77d2a47c1a79a8800fe05deef.png" /><br />  </p> <p>Model2开发模式将Servlet的概念引入架构体系中,使用它来分配视图层Jsp的显示页面,同时调用模型层的JavaBean来控制业务逻辑。</p> <p><strong>3、Model1和Model2的区别:</strong></p> <p>Model1:简单,适合小型项目的开发,但是Jsp的职责过于繁重,职责分工不明确。在后期的维护工作中,必将为此付出代价!</p> <p>Model2:相对于Model1来说,职责分工更为明确,在Model1的基础上,抽取了Servlet层,体现了一个分层的思想,适合大型的项目开发!(当时的评判标准是适合大型项目开发的,现在看起来已经过时了!)</p> <p>Model2看起来已经尽善尽美了,尽管如此,他还不能称之为一个比较完善的MVC设计模式!</p> <p><strong>4、Model1和Model2与三层的对比:</strong></p> <p>在Model2中,我们将Servlet抽取出单独的一层,和Jsp协作完成用户数据交互的工作,也就是表示层。那么作为三层结构来说,又做了什么样的改进呢?三层则是在此基础上,将JavaBean再一次进行分割:<strong>业务逻辑、数据持久化</strong>,三层如下:</p> <p>(1)表示层,JSP/Servlet; <br /> (2)业务逻辑层:业务规则; <br /> (3)持久化层:主要包装持久化的逻辑 ;<br /> <img alt="传统分层" class="img-thumbnail" src="/resources/assist/images/blog/bc45663830bc45bfa35251b49a7ecd31.png" /><br /> 各个的耦合性如下图:</p> <p><img alt="耦合度比较" class="img-thumbnail" src="/resources/assist/images/blog/7eff9d77e17e4c059d78a452f2f3b2ee.png" /><br />  </p> <p>Model1、Model2、三层是在解耦的基础上一步步进化而来,通过解耦我们可以进行进一步的抽象,以应对现实需求的变动。</p> <h2><strong>四、Web发展中级阶段、高级阶段和骨灰级阶段</strong></h2> <p>这一小节似乎有点应付,对于中级阶段,因为我没有用过EJB,在这里不敢妄加评论,以免误导大家。但是相信每一位接触过Spring的小伙伴,都应该知道Rod Johnson在2002年编写的《Expert One-to-One J2EE Design and Development》一书,Rod 在本书中对J2EE正统框架臃肿、低效、脱离现实的种种学院派做法提出了质疑,并以此书为指导思想,编写了interface21框架,也就是后来的Spring。</p> <p>对于高级阶段和骨灰级阶段是我们后期一系列文章的重点,本篇只作为一个阶段划分,不做过多的解释,因此让我们重新回到Web发展的初级阶段。</p> <h2><strong>五、Web发展初级阶段存在的问题</strong></h2> <p>经历过初级阶段的小伙伴肯定看得懂下边的一个项目结构,一个简单的MVC三层结构,使用JSP+Servlet+MySQL+JDBC技术,面向接口编程:<br /> <img alt="结构" class="img-thumbnail" src="/resources/assist/images/blog/e1ebf7b9cb22401380f4e0e5426049ea.png" /><br />  </p> <p><strong>1、面向接口编程的实例化对象</strong></p> <p>以用户管理模块为例,有一个UserDao接口,有一个接口的实现类UserDaoImpl<br />  </p> <p>由于是面向接口编程,因此我们在每次使用UserDao的时候,都要进行实例化一次,实例化代码如下:</p> <pre> <code class="language-java">UserDao userDao = new UserDaoImpl();</code></pre> <p>我们在每次使用UserDao的时候都需要进行实例化,当然不仅仅有UserDao需要进行实例化,还有很多需要进行实例化的,举例如下:<br /> <img alt="代码" class="img-thumbnail" src="/resources/assist/images/blog/437fdfff249e47779109f096e38cdec9.png" /><br />  </p> <p>可以看出,每一个方法中都需要进行实例化我们需要用到的接口的实现类,这就会存在大量的实例化对象,并且他们的生命周期可能就是从方法的调用开始到方法的调用结束为止,加大了GC回收的压力!</p> <p><strong>2、使用单利模式的一次改进</strong></p> <p>了解设计模式的可能会想到使用单利模式的方式来解决这个问题,以此来避免大量重复的创建对象,但是我们还要考虑到众多的这种对象的创建都需要改成单利模式的话,是一个耗时耗力的操作。</p> <p>对于这个系统来说,如果都把这种面向接口的对象实现类转换为单利模式的方式的话,大概也要写十几个或者上百个这种单例模式代码,而对于一个单利模式的写法来说,往往是模板式的代码,以静态内部类的方式实现代理模式如下:<br /> <img alt="代码" class="img-thumbnail" src="/resources/assist/images/blog/79cae2e5b3ea488f8e90b3737eddfc67.png" /><br />  </p> <p>可以看出,这种方式有两个问题:</p> <p>(1)业务代码与单利模式的模板代码放在一个类里,耦合性较高; <br /> (2)大量重复的单利模式的模板代码;</p> <p>从上述可以看出,使用的单利模式虽然从性能上有所提高,但是却加重了我们的开发成本。因此只会小规模的使用,例如我们操作JDBC的Utils对象等。</p> <p><strong>3、我们开发中遇到的痛点</strong></p> <p>    从上述代码的演进过程我们可以看得出来,我们即需要一个单利的对象来避免系统中大量重复对象的创建和销毁,又不想因为使用单利模式造成大量重复无用的模板代码和代码的耦合!</p> <p>    (突然想到一个段子,想和大家分享一下:产品经理在给甲方汇报方案的时候说了两种方案:一种是实用的,一种是美观的,问甲方希望选择哪一种?甲方说:有没有即实用又美观的!)</p> <p><strong>4、我们还能怎么做</strong></p> <p>    作为学院派的书生来说,我们可能会联想到“数据库连接池”,我们在获取数据库连接的时候会从这个池子中拿到一个连接的,假设这个数据库连接池很特殊,有且只能有N个数据库连接,并且每一个连接对象都不同(假设),那么这个不就相当于每一个连接都是单利的了吗?既可以避免大量对象的创建,也可以实现不会出现大量重复性的模板代码。</p> <p>因此,这里应该有一个大胆的想法,我们是否可以建立一个池子,将我们的接口实现类对象放入到这个池子中,我们在使用的时候直接从这个池子里边取就行了!</p> <p><strong>5、这个池子</strong></p> <p>    如果我们要创建这个池子,首先要确定需要把哪些对象放进这个池子,通过怎样的方式放进去,放进去之后如何进行管理,如何进行获取,池子中的每一个对象的生命周期是怎么样的等等这些东西都是我们需要考虑到的!</p> <p><strong>6、恭喜你</strong></p> <p>    如果你已经了解了上述Web演进的过程,以及我们想要创建的这个池子,那么恭喜你!你已经打开了Spring核心原理的大门了!</p> <p>    上述我们想要创建的池子其实就是Spring容器的雏形,将接口实现类的对象放进池子进行管理的过程其实也是Spring IOC依赖注入、控制反转的雏形!</p> <p>    Spring的依赖注入/控制反转就是从我们的配置文件或注解中的得到我们需要进行注入到Spring容器的实现类的信息,Spring IOC通过这些配置信息创建一个个单利的对象并放入Spring容器中,Spring容器可以看做是一个集合保存着我们的这些对象。</p> <p><strong>7、小总结</strong></p> <p>    上文中主要从一个切入点探讨了一下为什么有Spring,以及介绍了一下Spring IOC和Spring容器的基本雏形概念,当然还可以从其他方面进行切入。这里没有进一步探讨AOP的概念,对于新入门的小伙伴来说,这个确实有必要讨论一下,也决定在后续文章中由浅入深的探讨一下,而对于老手来说,其实我上边写的基本上是浪费大家时间的!</p> <h2><strong>六、总结</strong></h2> <p>    从历史的角度来说,不同时期的大革命在爆发之前,都会有一个蓄谋已久的“导火线”!Spring的出现,同样顺应了历史发展潮流,正式由于那个时期J2EE开发标准的种种弊端造就了Spring的出现!即使不是Spring,同样也会有其他类似的产品出现,只不过历史选择了Spring,Spring顺应了历史!没有切肤之痛,是不会体会到Spring带给我们的乐趣与快感!</p> <p>    同样的,每个时代都会有每一个时代的问题,Spring也是!正如十年前我们的计算机可能带不动一款游戏,今天我们的计算机也有可能带不动一款如今的游戏,同样十年后的计算机也会有一款他带不动的游戏出现!以一种发展的眼光去看Spring,就可以很好的理解Spring Boot是以一种什么样的角色出现在我们的面前了!</p> <p>    时代选择了Spring,同样Spring也被这个时代所选择着!你我只有不停的进步,不停地学习才能跟上这个时代!</p>
  • Spring 5 MVC 整合 Hibernate 5

    在这个Spring5教程中,学习创建Spring 5 MVC Web应用程序,处理表单提交,集成hibernate连接到后端数据库,以及添加用于输入表单字段验证的hibernate验证器。<h2>引言</h2>     在这个Spring5教程中,学习创建Spring 5 MVC Web应用程序,处理表单提交,集成hibernate连接到后端数据库,以及添加用于输入表单字段验证的hibernate验证器。<br /> <br />     我们将创建一个简单的屏幕,我们可以添加用户字段(名称和电子邮件)。 这些细节将首先验证,然后使用休眠存储在HSQL数据库中。 该页面也将列出所有存储的用户。 <h2>一.Spring MVC 5整合hibernate5开发环境准备</h2> <ul> <li>Eclipse Neon.2 +</li> <li>JDK 1.8 +</li> <li>Spring 5.0.0.RELEASE</li> <li>Hibernate 5.2.11.Final</li> <li>Hibernate validator 5.4.1.Final</li> <li>Servlets 3.1.0</li> <li>HSQLDB 1.8.0.10</li> <li>Tomcat 7 maven plugin 2.2</li> </ul> <h2>二.Spring MVC 5整合hibernate5项目结构图</h2> 该项目具有典型的Maven Web应用程序结构。<br /> <img alt="Spring5" class="img-thumbnail" src="/resources/assist/images/blog/2cd6c348063d40caabff4dfdc8e79010.png" /> <h2>三.Spring MVC 5整合hibernate5类图关系</h2> <img alt="" class="img-thumbnail" src="/resources/assist/images/blog/3bb67013c0b84472824f0936c8f82b6e.png" /> <h2>四.Spring MVC 5整合hibernate5 maven依赖</h2> 查找用于在pom.xml文件中运行此示例的项目依赖项。 <pre> <code class="language-xml"><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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.howtodoinjava.spring5.demo</groupId> <artifactId>spring5-mvc-hibernate-example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <failOnMissingWebXml>false</failOnMissingWebXml> <spring.version>5.0.0.RELEASE</spring.version> <hibernate.version>5.2.11.Final</hibernate.version> <hibernate.validator>5.4.1.Final</hibernate.validator> <c3p0.version>0.9.5.2</c3p0.version> <jstl.version>1.2.1</jstl.version> <tld.version>1.1.2</tld.version> <servlets.version>3.1.0</servlets.version> <jsp.version>2.3.1</jsp.version> <hsqldb.version>1.8.0.10</hsqldb.version> </properties> <dependencies> <!-- Spring MVC Dependency --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- Spring ORM --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <!-- Hibernate Core --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <!-- Hibernate-C3P0 Integration --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>${hibernate.version}</version> </dependency> <!-- c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>${c3p0.version}</version> </dependency> <!-- Hibernate Validator --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.validator}</version> </dependency> <!-- JSTL Dependency --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>${tld.version}</version> </dependency> <!-- Servlet Dependency --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlets.version}</version> <scope>provided</scope> </dependency> <!-- JSP Dependency --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>${jsp.version}</version> <scope>provided</scope> </dependency> <!-- HSQL Dependency --> <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>${hsqldb.version}</version> </dependency> </dependencies> <build> <sourceDirectory>src/main/java</sourceDirectory> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <path>/</path> </configuration> </plugin> </plugins> </build> </project></code></pre> <h2>五.配置Spring MVC 5 servlet分发器DispatcherServlet</h2>     随着Servlet 3.0规范的发布,可以用几乎没有xml来配置你的Servlet容器。 为此,Servlet规范中有ServletContainerInitializer。 在这个类中,你可以注册过滤器,监听器,servlet等,就像你在web.xml中一样。<br /> <br />     Spring提供了知道如何处理WebApplicationInitializer类的SpringServletContainerInitializer。 AbstractAnnotationConfigDispatcherServletInitializer类实现了内部实现WebApplicationInitializer的WebMvcConfigurer。 它注册一个ContextLoaderlistener(可选)和DispatcherServlet,并允许您轻松添加配置类来加载这两个类,并将过滤器应用于DispatcherServlet并提供servlet映射。<br />   <pre> <code class="language-java">public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { HibernateConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { WebMvcConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } }</code></pre> <h2>六.Spring Web MVC 5 配置</h2> Spring Web MVC配置如下。 <pre> <code class="language-java">import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.validation.Validator; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @EnableWebMvc @ComponentScan(basePackages = { "com.howtodoinjava.demo.spring"}) public class WebMvcConfig implements WebMvcConfigurer { @Bean public InternalResourceViewResolver resolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; } @Bean public MessageSource messageSource() { ResourceBundleMessageSource source = new ResourceBundleMessageSource(); source.setBasename("messages"); return source; } @Override public Validator getValidator() { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setValidationMessageSource(messageSource()); return validator; } }</code></pre> <ol> <li><code>WebMvcConfigurer</code> 定义了通过使用@EnableWebMvc自定义或添加到默认的<code>@EnableWebMvc</code>配置的选项。</li> <li><code>@EnableWebMvc</code> 启用默认的Spring MVC配置,并注册DispatcherServlet所期望的Spring MVC基础架构组件。</li> <li><code>@Configuration</code> 指示一个类声明了一个或多个@Bean方法,并且可以被Spring容器处理,以在运行时为这些bean生成bean定义和服务请求。</li> <li><code>@ComponentScan</code> 注释用于指定要扫描的基本包。任何用@Component和@Configuration注解的类都将被扫描。</li> <li><code>InternalResourceViewResolver</code> 有助于映射逻辑视图名称,以便在特定的预配置目录下直接查看文件。</li> <li><code>ResourceBundleMessageSource</code> 使用指定的基本名称访问资源包(这里是消息)。</li> <li><code>LocalValidatorFactoryBean</code> 引导一个<code>javax.validation.ValidationFactory</code> ,并通过Spring Validator接口以及JSR-303 Validator接口和<code>ValidatorFactory</code> 接口本身公开它。</li> </ol> <h2>七.Hibernate 配置</h2> 在例子中使用Hibernate配置。 <pre> <code class="language-java">import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScans; import org.springframework.context.annotation.Configuration; import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.howtodoinjava.demo.spring.model.User; @Configuration @EnableTransactionManagement public class HibernateConfig { @Autowired private ApplicationContext context; @Bean public LocalSessionFactoryBean getSessionFactory() { LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean(); factoryBean.setConfigLocation(context.getResource("classpath:hibernate.cfg.xml")); factoryBean.setAnnotatedClasses(User.class); return factoryBean; } @Bean public HibernateTransactionManager getTransactionManager() { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(getSessionFactory().getObject()); return transactionManager; } }</code></pre> <ul> <li><code>LocalSessionFactoryBean</code> 创建一个Hibernate <code>SessionFactory</code>. 这是在Spring应用程序上下文中设置共享Hibernate SessionFactory的常用方法。</li> <li><code>EnableTransactionManagement</code> 支持Spring的注解驱动事务管理功能。</li> <li><code>HibernateTransactionManager</code> 将Hibernate Session从指定的工厂绑定到线程,可能允许每个工厂有一个线程绑定的Session。 此事务管理器适用于使用单个Hibernate</li> <li><code>SessionFactory</code> 进行事务性数据访问的应用程序,但也支持事务内的直接<code>DataSource</code> 访问,即普通JDBC。</li> </ul> <strong>hibernate.cfg.xml:</strong> <pre> <code class="language-xml"><?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.archive.autodetection">class,hbm</property> <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property> <property name="hibernate.connection.username">sa</property> <property name="hibernate.connection.password"></property> <property name="hibernate.connection.url">jdbc:hsqldb:mem:howtodoinjava</property> <property name="hibernate.hbm2ddl.auto">create</property> <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.acquire_increment">2</property> <property name="hibernate.c3p0.acquire_increment">1800</property> <property name="hibernate.c3p0.max_statements">150</property> </session-factory> </hibernate-configuration></code></pre> <h2>八.Spring Controller and Path Mappings</h2> 控制器类有两个简单的GET和POST操作映射。 如果输入字段未被验证,则返回相同的表单bean以显示错误消息。 否则返回刷新视图。 <pre> <code class="language-java"> import java.util.Locale; import javax.validation.alid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import com.howtodoinjava.demo.spring.model.User; import com.howtodoinjava.demo.spring.service.UserService; @Controller public class UserController { @Autowired private UserService userService; @GetMapping("/") public String userForm(Locale locale, Model model) { model.addAttribute("users", userService.list()); return "editUsers"; } @ModelAttribute("user") public User formBackingObject() { return new User(); } @PostMapping("/addUser") public String saveUser(@ModelAttribute("user") @Valid User user, BindingResult result, Model model) { if (result.hasErrors()) { model.addAttribute("users", userService.list()); return "editUsers"; } userService.save(user); return "redirect:/"; } }</code></pre> <h2>九.Service and DAO 层</h2> 服务和DAO层是用@Service和@Repository注释标注的普通服务组件。 @交易注解应用于服务层以支持事务处理。<br /> <br /> <code>UserService</code> and <code>UserServiceImpl</code><br />   <pre> <code class="language-java">public interface UserService { void save(User user); List<User> list(); } @Service public class UserServiceImp implements UserService { @Autowired private UserDao userDao; @Transactional public void save(User user) { userDao.save(user); } @Transactional(readOnly = true) public List<User> list() { return userDao.list(); } }</code></pre> <code>UserDao</code> and <code>UserDaoImp</code><br />   <pre> <code class="language-java">public interface UserDao { void save(User user); List<User> list(); } @Repository public class UserDaoImp implements UserDao { @Autowired private SessionFactory sessionFactory; @Override public void save(User user) { sessionFactory.getCurrentSession().save(user); } @Override public List<User> list() { @SuppressWarnings("unchecked") TypedQuery<User> query = sessionFactory.getCurrentSession().createQuery("from User"); return query.getResultList(); } }</code></pre> User<br />   <pre> <code class="language-java">import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; @Entity @Table(name = "TBL_USERS") public class User { @Id @GeneratedValue @Column(name = "USER_ID") private Long id; @Column(name = "USER_NAME") @Size(max = 20, min = 3, message = "{user.name.invalid}") @NotEmpty(message="Please Enter your name") private String name; @Column(name = "USER_EMAIL", unique = true) @Email(message = "{user.email.invalid}") @NotEmpty(message="Please Enter your email") private String email; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }</code></pre> <h2>十.页面和消息</h2> 最后,使用JSP文件和消息资源包<br /> <br /> editUsers.jsp<br />   <pre> <code class="language-html"><%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Spring5 MVC Hibernate Demo</title> <style type="text/css"> .error { color: red; } table { width: 50%; border-collapse: collapse; border-spacing: 0px; } table td { border: 1px solid #565454; padding: 20px; } </style> </head> <body> <h1>Input Form</h1> <form:form action="addUser" method="post" modelAttribute="user"> <table> <tr> <td>Name</td> <td> <form:input path="name" /> <br /> <form:errors path="name" cssClass="error" /> </td> </tr> <tr> <td>Email</td> <td> <form:input path="email" /> <br /> <form:errors path="email" cssClass="error" /> </td> </tr> <tr> <td colspan="2"><button type="submit">Submit</button></td> </tr> </table> </form:form> <h2>Users List</h2> <table> <tr> <td><strong>Name</strong></td> <td><strong>Email</strong></td> </tr> <c:forEach items="${users}" var="user"> <tr> <td>${user.name}</td> <td>${user.email}</td> </tr> </c:forEach> </table> </body> </html></code></pre> messages.properties<br />   <pre> <code class="language-html">user.name.invalid = Name must be between {2} and {1} characters. user.email.invalid = Please enter valid email address.</code></pre> <h2>十一.演示这个栗子</h2> 让我们使用maven tomcat7插件运行应用程序。 执行maven target:tomcat7:run。<br /> 访问URL: <code>http://localhost:8080</code><br /> Initial Screen<br /> <img alt="Initial Screen" class="img-thumbnail" src="/resources/assist/images/blog/830164ad1b5448dab1aa39d340300c95.png" /><br /> 无效的输入验证<br /> <img alt="无效的输入验证" class="img-thumbnail" src="/resources/assist/images/blog/8ddf9070177c4ce3a00c5dfe4b099950.png" /><br /> 有效的表格提交<br /> <img alt="有效的表格提交" class="img-thumbnail" src="/resources/assist/images/blog/6ef29b6dbc1f4fb7954a3cb9bac38159.png" /><br /> 检查服务器日志: <pre> <code class="language-html">Hibernate: call next value for hibernate_sequence Hibernate: insert into TBL_USERS (USER_EMAIL, USER_NAME, USER_ID) values (?, ?, ?) Hibernate: select user0_.USER_ID as USER_ID1_0_, user0_.USER_EMAIL as USER_EMA2_0_, user0_.USER_NAME as USER_NAM3_0_ from TBL_USERS user0_</code></pre> <a href="https://howtodoinjava.com/wp-content/downloads/spring5-mvc-hibernate-example.zip" rel="external nofollow" target="_blank">Sourcecode Download</a>
  • java常用框架SpringMVC3/4入门教程

    SpringMVC框架是一个java里面非常轻量级的mvc框架之一,与spring框架同源,整合方便快捷.java常用框架SpringMVC3/4入门教程 <p>1SpringMVC3</p> <p>1.1项目结构图</p> <img alt="java常用框架SpringMVC3/4入门教程" src="/resources/assist/images/blog/50f775fc-8470-4e98-bab8-a9195d8d2671.png" style="height:527px; width:313px" /> <p>1.2Pom.xml</p> <pre> <code class="language-xml"><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>seven.org</groupId>    <artifactId>springmvc3</artifactId>    <packaging>war</packaging>    <version>0.0.1-SNAPSHOT</version>    <name>springmvc3 Maven Webapp</name>    <url>http://maven.apache.org</url>    <properties>       <junit.version>4.12</junit.version>       <spring.version>3.2.2.RELEASE</spring.version>       <org.codehaus.jackson.version>1.9.13</org.codehaus.jackson.version>       <commons-fileupload.version>1.3.1</commons-fileupload.version>    </properties>    <dependencies>       <dependency>          <!-- test -->          <groupId>junit</groupId>          <artifactId>junit</artifactId>          <version>${junit.version}</version>          <scope>test</scope>       </dependency>         <!-- spring framework start -->       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-core</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-context</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-web</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-webmvc</artifactId>          <version>${spring.version}</version>       </dependency>       <!-- spring framework end -->         <!-- 为SpringMVC提供json数据类型支持 -->         <!-- 注意,新版的 jackson-core-asl已经升级为Group:com.fasterxml.jackson.core|Artifact:jackson-core在SpringMVC4中需要使用新版 -->       <dependency>          <groupId>org.codehaus.jackson</groupId>          <artifactId>jackson-core-asl</artifactId>          <version>${org.codehaus.jackson.version}</version>       </dependency>       <dependency>          <groupId>org.codehaus.jackson</groupId>          <artifactId>jackson-mapper-asl</artifactId>          <version>${org.codehaus.jackson.version}</version>       </dependency>         <!-- el 标签库 -->       <!-- standard.jar -->       <dependency>          <groupId>taglibs</groupId>          <artifactId>standard</artifactId>          <version>1.1.2</version>       </dependency>       <!-- JSTL -->       <dependency>          <groupId>javax.servlet</groupId>          <artifactId>jstl</artifactId>          <version>1.1.2</version>       </dependency>       <!-- /el 标签库 -->         <!-- 文件上传下载 -->       <dependency>          <groupId>commons-fileupload</groupId>          <artifactId>commons-fileupload</artifactId>          <version>${commons-fileupload.version}</version>       </dependency>         <!-- slf4j 和 log4j合用的Maven配置 -->       <dependency>          <groupId>org.slf4j</groupId>          <artifactId>slf4j-log4j12</artifactId>          <version>1.7.2</version>       </dependency>      </dependencies>    <build>       <finalName>springmvc3</finalName>    </build> </project></code></pre>   <p>1.3web.xml</p> <pre> <code class="language-xml"><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    version="3.0">    <display-name>Archetype Created Web Application</display-name>      <!-- 字符集处理 -->    <filter>       <filter-name>CharacterEncodingFilter</filter-name>       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>       <init-param>          <param-name>encoding</param-name>          <param-value>utf-8</param-value>       </init-param>    </filter>    <filter-mapping>       <filter-name>CharacterEncodingFilter</filter-name>       <url-pattern>/*</url-pattern>    </filter-mapping>        <!-- spring 配置 -->    <context-param>       <param-name>contextConfigLocation</param-name>       <param-value>classpath:/cfg/spring/spring-beans.xml</param-value>    </context-param>    <listener>       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>      <!-- 配置缓存清除监听器,负责处理由 JavaBean Introspector 功能而引起的缓存泄露 -->    <listener>       <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>    </listener>        <!-- springMVC配置 -->    <servlet>       <servlet-name>springMVCSerlet</servlet-name>       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>       <init-param>          <param-name>contextConfigLocation</param-name>          <param-value>classpath:/cfg/spring/spring-servlet.xml</param-value>       </init-param>       <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>       <servlet-name>springMVCSerlet</servlet-name>       <url-pattern>/</url-pattern>    </servlet-mapping>      <!-- 添加下面容器,防止同一个服务器部署多个项目web.root冲突 -->    <context-param>       <param-name>webAppRootKey</param-name>       <param-value>springMVC3</param-value>    </context-param>        <!-- log4j配置 -->    <context-param>       <param-name>log4jConfigLocation</param-name>       <param-value>classpath:/cfg/log/Log4j.properties</param-value>    </context-param>    <context-param>       <param-name>log4jRefreshInterval</param-name>       <param-value>60000</param-value>    </context-param>      <!-- session timeout -->    <session-config>       <!-- 分钟 -->       <session-timeout>60</session-timeout>    </session-config>      <!-- welcome page -->    <welcome-file-list>       <welcome-file>index.html</welcome-file>       <welcome-file>index.jsp</welcome-file>    </welcome-file-list>      <!-- session copy -->    <distributable /> </web-app></code></pre>   <p>1.4spring-servlet.xml</p> <pre> <code class="language-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.2.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-3.2.xsd ">      <!-- 自动扫描包 -->    <context:component-scan base-package="com" />      <!-- 注解驱动 -->    <mvc:annotation-driven />    <mvc:default-servlet-handler />    <!-- 资源管理不拦截 -->    <mvc:resources location="/resources/" mapping="/resources/**" />    <mvc:resources location="/upload/" mapping="/upload/**" />      <!-- 内部资源视图解析器 prefix + logicName + suffix /WEB-INF/jsps/ + index + .jsp -->    <bean id="internalResourceViewResolver"       class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <!-- 前缀 -->       <property name="prefix" value="/WEB-INF/pages/" />       <!-- 后缀 -->       <property name="suffix" value="" />    </bean>        <!-- 上传图片/文件需要配置 -->    <bean id="multipartResolver"       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">       <property name="maxUploadSize" value="104857600" />       <property name="maxInMemorySize" value="4096" />    </bean>        <!-- 配置JSON支持 start -->    <bean id="mappingJacksonHttpMessageConverter"    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">       <property name="supportedMediaTypes">          <list>             <!-- 处理返回的json数据的编码,默认是ISO-88859-1 -->             <value>text/html;charset=UTF-8</value>          </list>       </property>    </bean>    <bean    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">       <!-- messageConverters属性中加入 mappingJacksonHttpMessageConverter用来处理json数据类行 -->       <property name="messageConverters">          <list>             <ref bean="mappingJacksonHttpMessageConverter" />          </list>       </property>    </bean>    <!-- 配置JSON支持 end -->     </beans></code></pre> <br /> 1.5spring-beans.xml <pre> <code class="language-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" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jpa="http://www.springframework.org/schema/data/jpa"    xsi:schemaLocation="http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd               http://www.springframework.org/schema/aop             http://www.springframework.org/schema/aop/spring-aop-3.2.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-3.2.xsd             http://www.springframework.org/schema/tx             http://www.springframework.org/schema/tx/spring-tx-3.2.xsd             http://www.springframework.org/schema/data/jpa             http://www.springframework.org/schema/data/jpa/spring-jpa.xsd ">    <context:annotation-config />    <!-- 启动自动扫描该包下所有的注解(如@controller) -->    <context:component-scan base-package="com" />   </beans>  </code></pre>   <p>1.6Log4j配置文件</p> <pre> <code>#defind the rooeLogger ,the rootlogger min level is INFO,and two way to output log log4j.rootLogger = INFO,FILE,CONSOLE,DATABASE   #---------------------------------------------------------------------- #defind the FILE as file everyday                                     | #---------------------------------------------------------------------- log4j.appender.FILE = org.apache.log4j.DailyRollingFileAppender   #the log min level set as INFO log4j.appender.FILE.Threshold=INFO   #log file encoding set UTF-8 log4j.appender.FILE.encoding=UTF-8   #log file path log4j.appender.FILE.File=/home/tomcat/log/springmvc3/springmvc3   #log file name append log4j.appender.FILE.DatePattern='_'yyyy-MM-dd'.log'   #Immediate write the log is true log4j.appender.FILE.ImmediateFlush=true   #the layout of the log log4j.appender.FILE.layout=org.apache.log4j.PatternLayout   #the detail layout of log  in the log file log4j.appender.FILE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} Springmvc3 %-5p [%c:%L] | %m%n   #------------------------------------------------------------------------- #this use the 'org.apache.log4j.ConsoleAppender' to output in the Console| #------------------------------------------------------------------------- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender   #output min level is INFO log4j.appender.Threshold=INFO   #the output target is Console log4j.appender.CONSOLE.Target=System.out   #the layout of the log log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} springmvc3 %-5p | %m%n   #---------------------------------------------------------------------------- #insert the log into database                                               | #---------------------------------------------------------------------------- log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender #The jdbc url log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/springmvc3 #The jdbc driver log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver #DB user log4j.appender.DATABASE.user=root #DB password log4j.appender.DATABASE.password=root #sql log4j.appender.DATABASE.sql=INSERT INTO zhl_log (operationTime,logLevel,logClass,logDetail)  VALUES ("%d{yyyy-MM-dd HH:mm:ss}", "%-5p","%F:%L", "%m") #layout log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout #layout detail log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</code></pre> <br /> 1.7测试vo <pre> <code class="language-java">package com.xqlee.springmvc.vo;   /**  *  *  * <pre>  * @功能说明 [测试bean]  * @其他说明 [暂无]  * @文件编码 [UTF-8]  * @所属包名 [com.xqlee.springmvc.vo]  * @项目名称 [cdws]  * @创建日期 []  * @创建人员 [lxq]  * @最后修改 []  * @修改说明 [暂无更新]  * @修改人员 [lxq]  * @公司组织 [org]  * @版本说明 [v 1.0]  *  * </pre>  */ public class Tobject {      private String id;    private String name;    private String num;      public Tobject(String id, String name, String num) {       this.id = id;       this.name = name;       this.num = num;    }      public String getId() {       return id;    }      public void setId(String id) {       this.id = id;    }      public String getName() {       return name;    }      public void setName(String name) {       this.name = name;    }      public String getNum() {       return num;    }      public void setNum(String num) {       this.num = num;    }   }</code></pre> <br /> 1.8测试controller <pre> <code class="language-java">package com.xqlee.springmvc.controller;   import java.util.Vector;   import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;   import com.xqlee.springmvc.vo.Tobject;   /**  *  *  * <pre>  * @功能说明 [测试类]  * @其他说明 [暂无]  * @文件编码 [UTF-8]  * @所属包名 [com.xqlee.springmvc.controller]  * @项目名称 [cdws]  * @创建日期 []  * @创建人员 [lxq]  * @最后修改 []  * @修改说明 [暂无更新]  * @修改人员 [lxq]  * @公司组织 [org]  * @版本说明 [v 1.0]  *  * </pre>  */ @Controller(value = "/beanTestController.do") public class BeanTestController {    @RequestMapping(params = "method=Vector")    // @ResponseBody    public Object testVector(HttpServletRequest request,          HttpServletResponse response) {       // 创建容器       Vector<Tobject> vtb = new Vector<Tobject>();       Tobject tb;       for (int i = 0; i <= 5; i++) {          tb = new Tobject("ID-" + i, "名称Name-" + i, "Num-" + i);          vtb.add(tb);       }       request.setAttribute("vtb", vtb);       return "../../vector.jsp";    }      @RequestMapping(params = "method=testJson")    @ResponseBody    public Object testJson(HttpServletRequest request,          HttpServletResponse response) {       // 创建容器       Vector<Tobject> vtb = new Vector<Tobject>();       Tobject tb;       for (int i = 0; i <= 5; i++) {          tb = new Tobject("ID-" + i, "名称Name-" + i, "Num-" + i);          vtb.add(tb);       }       return vtb;    }   }</code></pre>   <p>1.9index.jsp</p> <pre> <code class="language-html"><!DOCTYPE> <html> <body>    <h2>Hello World!</h2>    <a href="beanTestController.do?method=Vector">Vector Test</a> </body> </html></code></pre> <br /> 1.10vector.jsp <pre> <code class="language-html"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE> <html> <body>    <table border='1'>       <thead>          <tr>             <td>ID</td>             <td>Name</td>             <td>Num</td>          </tr>       </thead>       <tbody>          <c:forEach items="${vtb}" var="Object">             <tr>                 <td>${Object.id}</td>                 <td>${Object.name}</td>                 <td>${Object.num}</td>             </tr>          </c:forEach>       </tbody>    </table>     </body> </html></code></pre> <br /> 2 SpringMVC4 <p>2.1项目结构图</p> <img alt="2" src="/resources/assist/images/blog/63555b40-5fa1-41e6-9d7c-3d9e088a6223.png" style="height:510px; width:387px" /> <p>2.2pom.xml</p> <pre> <code class="language-xml"><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>seven.org</groupId>    <artifactId>springMVC</artifactId>    <packaging>war</packaging>    <version>0.0.1-SNAPSHOT</version>    <name>springMVC Maven Webapp</name>    <url>http://maven.apache.org</url>    <!-- 属性版本 -->    <properties>       <junit.version>4.12</junit.version>       <spring.version>4.1.7.RELEASE</spring.version>       <org.slf4j.version>1.7.2</org.slf4j.version>       <mysql.driver.version>5.1.32</mysql.driver.version>    <com.fasterxml.jackson.jaxrs.version>2.4.1</com.fasterxml.jackson.jaxrs.version>       <commons-fileupload.version>1.3.1</commons-fileupload.version>      </properties>    <dependencies>         <!-- 测试所需 -->       <dependency>          <groupId>junit</groupId>          <artifactId>junit</artifactId>          <version>${junit.version}</version>          <scope>test</scope>       </dependency>         <!-- spring core -->       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-core</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-context</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-web</artifactId>          <version>${spring.version}</version>       </dependency>       <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-webmvc</artifactId>          <version>${spring.version}</version>       </dependency>         <!-- MySQL数据库驱动 导入 start -->       <dependency>          <groupId>mysql</groupId>          <artifactId>mysql-connector-java</artifactId>          <version>${mysql.driver.version}</version>       </dependency>       <!-- MySQL数据库驱动 导入 end -->           <!-- el 标签库 -->       <!-- standard.jar -->       <dependency>          <groupId>taglibs</groupId>          <artifactId>standard</artifactId>          <version>1.1.2</version>       </dependency>       <!-- JSTL -->       <dependency>          <groupId>javax.servlet</groupId>          <artifactId>jstl</artifactId>          <version>1.1.2</version>       </dependency>       <!-- /el 标签库 -->         <!-- 处理json -->       <dependency>          <groupId>com.fasterxml.jackson.jaxrs</groupId>          <artifactId>jackson-jaxrs-xml-provider</artifactId>          <version>${com.fasterxml.jackson.jaxrs.version}</version>       </dependency>         <!-- 文件上传下载 -->       <dependency>          <groupId>commons-fileupload</groupId>          <artifactId>commons-fileupload</artifactId>          <version>${commons-fileupload.version}</version>       </dependency>         <!-- slf4j 和 log4j合用的Maven配置 -->       <dependency>          <groupId>org.slf4j</groupId>          <artifactId>slf4j-log4j12</artifactId>          <version>${org.slf4j.version}</version>       </dependency>      </dependencies>    <build>       <finalName>springMVC</finalName>    </build> </project></code></pre> <br /> 2.3web.xml <pre> <code class="language-xml"><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    version="3.0">    <display-name>Archetype Created Web Application</display-name>      <!-- 字符集处理 -->    <filter>       <filter-name>CharacterEncodingFilter</filter-name>       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>       <init-param>          <param-name>encoding</param-name>          <param-value>utf-8</param-value>       </init-param>    </filter>    <filter-mapping>       <filter-name>CharacterEncodingFilter</filter-name>       <url-pattern>/*</url-pattern>    </filter-mapping>        <!-- spring 核心配置 -->    <context-param>       <param-name>contextConfigLocation</param-name>       <param-value>classpath:/cfg/spring/spring-beans.xml</param-value>    </context-param>    <listener>       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>      <!-- 配置缓存清除监听器,负责处理由 JavaBean Introspector 功能而引起的缓存泄露 -->    <listener>       <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>    </listener>        <!-- springMVC配置 -->    <servlet>       <servlet-name>springMVCSerlet</servlet-name>       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>       <init-param>          <param-name>contextConfigLocation</param-name>          <param-value>classpath:/cfg/spring/spring-servlet.xml</param-value>       </init-param>       <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>       <servlet-name>springMVCSerlet</servlet-name>       <url-pattern>/</url-pattern>    </servlet-mapping>      <!-- 添加下面容器,防止同一个服务器部署多个项目web.root冲突 -->    <context-param>       <param-name>webAppRootKey</param-name>       <param-value>springMVC4</param-value>    </context-param>      <!-- session timeout -->    <session-config>       <!-- 分钟 -->       <session-timeout>60</session-timeout>    </session-config>      <!-- log4j配置 -->    <context-param>       <param-name>log4jConfigLocation</param-name>       <param-value>classpath:/cfg/log/Log4j.properties</param-value>    </context-param>    <context-param>       <param-name>log4jRefreshInterval</param-name>       <param-value>60000</param-value>    </context-param>    <!--添加监听 -->    <listener>       <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>    </listener>    <!-- /log4j配置 -->      <!-- welcome page -->    <welcome-file-list>       <welcome-file>index.html</welcome-file>       <welcome-file>index.jsp</welcome-file>    </welcome-file-list>      <!-- session copy -->    <distributable /> </web-app></code></pre>   <p>2.4 weblogic.xml</p> <pre> <code class="language-xml"><?xml version="1.0" encoding="UTF-8"?> <weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd    http://xmlns.oracle.com/weblogic/weblogic-web-app    http://xmlns.oracle.com/weblogic/weblogic-web-app/1.2/weblogic-web-app.xsd">      <container-descriptor>       <!-- 针对weblogic10以下的版本使用该语句,不能与厦门的prefer-application-packages同时使用 -->       <!-- <prefer-web-inf-classes>true</prefer-web-inf-classes> -->       <!-- 针对weblogic10及以上的版本如果上面语句无法成功使用该语句,不能与厦门的prefer-web-inf-classes同时使用 -->       <prefer-application-packages>          <package-name>org.apache.commons.lang.*</package-name>          <package-name>antlr.*</package-name>          <package-name>org.hibernate.*</package-name>          <package-name>javax.persistence.*</package-name>       </prefer-application-packages>    </container-descriptor> </weblogic-web-app></code></pre>   <p>2.5spring-servlet.xml</p> <pre> <code class="language-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-4.1.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-4.1.xsd ">      <!-- 自动扫描controller包下所有 -->    <context:component-scan base-package="com.xqlee.springmvc.controller" />    <!-- 注解驱动 -->    <mvc:annotation-driven />    <mvc:default-servlet-handler />    <!-- 资源管理不拦截 -->    <mvc:resources location="/resources/" mapping="/resources/**" />    <mvc:resources location="/upload/" mapping="/upload/**" />      <!-- 内部资源视图解析器 prefix + logicName + suffix /WEB-INF/jsps/ + index + .jsp -->    <bean id="internalResourceViewResolver"       class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <!-- 前缀 -->       <property name="prefix" value="/WEB-INF/pages/" />       <!-- 后缀 -->       <property name="suffix" value="" />    </bean>      <!-- 处理在controller中使用注解@ResponseBody标签返回JSON数据 Start -->    <!-- 注意[由于我在pom.xml引入的是2.4.1版本]:所以class=org.springframework.http.converter.json.MappingJackson2HttpMessageConverter -->    <!-- [如果pom.xml引入的是1.xx版本]class=org.springframework.http.converter.json.MappingJacksonHttpMessageConverter -->    <bean id="mappingJackson2HttpMessageConverter"    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">       <property name="supportedMediaTypes">          <list>             <value>text/html;charset=UTF-8</value>             <value>text/json;charset=UTF-8</value>             <value>application/json;charset=UTF-8</value>          </list>       </property>    </bean>    <bean    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">       <property name="messageConverters">          <list>             <ref bean="mappingJackson2HttpMessageConverter" />          </list>       </property>    </bean>    <!-- JSON数据处理 End -->      <!-- 上传图片/文件需要配置 -->    <bean id="multipartResolver"       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">       <property name="maxUploadSize" value="-1" /><!-- -1表示没有限制 -->       <property name="maxInMemorySize" value="4096" />    </bean>   </beans></code></pre>   <p>2.6spring-beans.xml</p> <pre> <code class="language-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" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jpa="http://www.springframework.org/schema/data/jpa"    xsi:schemaLocation="http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans-4.1.xsd             http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd               http://www.springframework.org/schema/aop             http://www.springframework.org/schema/aop/spring-aop-4.1.xsd             http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context-4.1.xsd             http://www.springframework.org/schema/tx             http://www.springframework.org/schema/tx/spring-tx-4.1.xsd             http://www.springframework.org/schema/data/jpa             http://www.springframework.org/schema/data/jpa/spring-jpa.xsd ">    <context:annotation-config />    <!-- 启动自动扫描该包下所有的注解(如@controller) 一般扫描service,entity,dao,controller由springMVC扫描 -->    <context:component-scan       base-package="com.xqlee.springmvc.service,com.xqlee.springmvc.entity,com.xqlee.springmvc.dao" /> </beans></code></pre>   <p>2.7 Log4j配置文件</p> <pre> <code>#defind the rooeLogger ,the rootlogger min level is INFO,and two way to output log log4j.rootLogger = INFO,FILE,CONSOLE,DATABASE   #---------------------------------------------------------------------- #defind the FILE as file everyday                                     | #---------------------------------------------------------------------- #log4j.appender.FILE = org.apache.log4j.DailyRollingFileAppender   #the log min level set as INFO #log4j.appender.FILE.Threshold=INFO   #log file encoding set UTF-8 #log4j.appender.FILE.encoding=UTF-8   #log file path #log4j.appender.FILE.File=/home/tomcat/log/springmvc4/springmvc4   #log file name append #log4j.appender.FILE.DatePattern='_'yyyy-MM-dd'.log'   #Immediate write the log is true #log4j.appender.FILE.ImmediateFlush=true   #the layout of the log #log4j.appender.FILE.layout=org.apache.log4j.PatternLayout   #the detail layout of log  in the log file #log4j.appender.FILE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} springmvc4 %-5p [%c:%L] | %m%n   #------------------------------------------------------------------------- #this use the 'org.apache.log4j.ConsoleAppender' to output in the Console| #------------------------------------------------------------------------- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender   #output min level is INFO log4j.appender.Threshold=INFO   #the output target is Console log4j.appender.CONSOLE.Target=System.out   #the layout of the log log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} springmvc4 %-5p | %m%n   #---------------------------------------------------------------------------- #insert the log into database                                               | #---------------------------------------------------------------------------- #log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender #The jdbc url #log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/springmvc4 #The jdbc driver #log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver #DB user #log4j.appender.DATABASE.user=root #DB password #log4j.appender.DATABASE.password=root #sql #log4j.appender.DATABASE.sql=INSERT INTO zhl_log (operationTime,logLevel,logClass,logDetail)  VALUES ("%d{yyyy-MM-dd HH:mm:ss}", "%-5p","%F:%L", "%m") #layout #log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout #layout detail #log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n</code></pre>   <p>2.8测试vo</p> <pre> <code class="language-java">package com.xqlee.springmvc.vo;   /**  *  *  * <pre>  * @功能说明 [测试bean]  * @其他说明 [暂无]  * @文件编码 [UTF-8]  * @所属包名 [com.xqlee.springmvc.vo]  * @项目名称 [cdws]  * @创建日期 []  * @创建人员 [lxq]  * @最后修改 []  * @修改说明 [暂无更新]  * @修改人员 [lxq]  * @公司组织 [org]  * @版本说明 [v 1.0]  *  * </pre>  */ public class User {      private String id;    private String name;    private String num;      public User(String id, String name, String num) {       this.id = id;       this.name = name;       this.num = num;    }      public String getId() {       return id;    }      public void setId(String id) {       this.id = id;    }      public String getName() {       return name;    }      public void setName(String name) {       this.name = name;    }      public String getNum() {       return num;    }      public void setNum(String num) {       this.num = num;    }   }</code></pre>   <p>2.9测试controller</p> <pre> <code class="language-java">package com.xqlee.springmvc.controller;   import java.util.Vector;   import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;   import com.xqlee.springmvc.vo.User;   /**  *  *  * <pre>  * &#64;功能说明 [测试类]  * &#64;其他说明 [暂无]  * &#64;文件编码 [UTF-8]  * &#64;所属包名 [com.xqlee.springmvc.controller]  * &#64;项目名称 [cdws]  * &#64;创建日期 []  * &#64;创建人员 [lxq]  * &#64;最后修改 []  * &#64;修改说明 [暂无更新]  * &#64;修改人员 [lxq]  * &#64;公司组织 [org]  * &#64;版本说明 [v 1.0]  *  * </pre>  */ @Controller(value = "/beanTestController.do") public class TestController {    /** 日志 **/    private static final Log log = LogFactory.getLog(TestController.class);      @RequestMapping(params = "method=Vector")    // @ResponseBody    public Object testVector(HttpServletRequest request, HttpServletResponse response) {       // 创建容器       Vector<User> vtb = new Vector<User>();       User tb;       for (int i = 0; i <= 5; i++) {          tb = new User("ID-" + i, "小Name-" + i, "李Num-" + i);          vtb.add(tb);       }       request.setAttribute("vtb", vtb);       log.info("即将跳转.....");       return "../../vector.jsp";    } }</code></pre>   <p>2.10 index.jsp</p> <pre> <code class="language-html"><!DOCTYPE> <html> <body>    <h2>Hello World!</h2>    <a href="beanTestController.do?method=Vector">Vector Test</a> </body> </html></code></pre>   <p>2.11 vector.jsp</p> <pre> <code class="language-html"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE> <html> <body>    <table border='1'>       <thead>          <tr>             <td>ID</td>             <td>Name</td>             <td>Num</td>          </tr>       </thead>       <tbody>          <c:forEach items="${vtb}" var="Object">             <tr>                 <td>${Object.id}</td>                 <td>${Object.name}</td>                 <td>${Object.num}</td>             </tr>          </c:forEach>       </tbody>    </table>     </body> </html></code></pre>   <p>2.12运行结果</p> <img alt="3" src="/resources/assist/images/blog/d439127f-c160-4faa-a47b-1f3118f87ba5.png" style="height:213px; width:422px" /><br /> <img alt="4" src="/resources/assist/images/blog/46005b58-d05f-4bab-b517-11ed209014c9.png" style="height:486px; width:611px" /><br />  
  • jps,jvm调优_JPS使用_Java虚拟机性能监控与调优实战

    本文针对Java虚拟机对程序性能影响,通过设置不同的Java虚拟机参数来提升程序的性能。首先从Java虚拟机各个性能方面来进行监控,找出Java虚拟机中可能对程序性能影响较大的,然后先通过小实验来证明对程序性能的影响,确定了对程序性能影响较大的指标。最后通过一个实际的项目案例来进行调优,给一定的系统资源下,使网站吞吐量达到最大。<h2>引言</h2>     本文针对Java虚拟机对程序性能影响,通过设置不同的Java虚拟机参数来提升程序的性能。首先从Java虚拟机各个性能方面来进行监控,找出Java虚拟机中可能对程序性能影响较大的,然后先通过小实验来证明对程序性能的影响,确定了对程序性能影响较大的指标。最后通过一个实际的项目案例来进行调优,给一定的系统资源下,使网站吞吐量达到最大。 <h2><br /> 一.<strong>监控的指标和工具</strong></h2> <blockquote> <p><strong>jps</strong>:虚拟机进程状况工具(JDK自带,安装JDK后配置环境变量,命令行可以直接敲出来)</p> </blockquote> 利用<strong>jps</strong>工具可以显示当前虚拟机中运行的java进程,并且jps后面可以跟参数,-l是输出主类名,-v可以输出JVM启动时候的参数配置。写了如下一段java代码做了个测试。 <pre> <code class="language-java">package demo.test; public class TraditionalThread { public static void main(String[] args) { Thread thread = new Thread() { public void run() { while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1:" + Thread.currentThread().getName()); } } }; thread.start(); Thread thread2 = new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2:" + Thread.currentThread().getName()); } } }); thread2.start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Runnable" + Thread.currentThread().getName()); } } }) { public void run() { while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("3:" + Thread.currentThread().getName()); } } }.start(); } } </code></pre> 运行上面的Java程序,打开windows系统的控制台输入命令: <pre> <code class="language-html">jps -l</code></pre> <img alt="jps监控java运行进程" class="img-thumbnail" src="/resources/assist/images/blog/f8ea6d3ade5549aa87200039317f2d3c.png" /><br /> jsp输出JVM启动时参数<br /> <img alt="jsp输出JVM启动时参数" class="img-thumbnail" src="/resources/assist/images/blog/94f0819e548d483b896c4749b34961a3.png" /><br /> <br />     如图所示有个TraditionalThread进程在运行,显示主类的全名,进程号为3048,jps工具本身也是一个java程序,进程号为10388,进程号3048就是main函数所在的进程了。一共有3个进程在运行。如图3.2所示,jsp –v输出了JVM启动加载jdk里面内置的tools.jar等等,JVM的参数配置,堆内存最小为1024M,堆内存最大为1024M,永久代最大<br /> 为1024M。 <blockquote> <p><strong>jstat</strong>:虚拟机运行时信息监控</p> </blockquote> jstat是用来监控JVM运行时的状态信息的工具,可以查看JVM中类的装载、堆内存的详细信息、垃圾收集等等。我们编写如下测试代码 <pre> <code class="language-java">package demo.test; import java.util.ArrayList; import java.util.List; public class HeapOOM { static class OOMObject { } public static void main(String[] args) { List<OOMObject> list = new ArrayList<OOMObject>(); while (true) { list.add(new OOMObject()); } } } </code></pre> <img alt="" class="img-thumbnail" src="/resources/assist/images/blog/b0ba396bc2684b7c98f2f82a4f930136.png" /><br /> 如图所示,Loaded表示加载了439个类,Bytes表示载入类的合计大小,Unloaded表示卸载类数量为0个,第2个Bytes表示卸载类的大小,Time表示在加载类和卸载类上所花费的时间。<br /> <br /> 同样通过JPS命令获取进程号,然后通过jstat查看内存回收情况:<br /> S0C表示是s0的大小为580608字节,S1C表示是s1的大小为580608字节,S0U表示是s0区已使用大小为0,S1U表示是s1区已使用大小为222611.2,Eden(EU表示Eden)大小为373248字节,Eden:S1 :S0 = 8:1:1,满足之前的分代内存模型。EU表示Eden已使用373248字节,OC表示老年代大小为3485696个字节,OU表示老年代已使用3485192.3字节。YGC表示新生代发生GC的次数为13次,YGCT表示新生代GC的耗时为17.709秒,FGC表示Full GC的次数为54次,FGCT耗时为888.770秒,GCT表示GC的总耗时为906.479秒。<br /> <img alt="" class="img-thumbnail" src="/resources/assist/images/blog/72a8a7fb2431494f89a9ffcd837bd631.png" /><br /> s0区域使用百分比为0,s1区域使用百分比为0,(E)Eden区域使用大小100%,(O)老年代区域使用大小为99.99% 说明老年代已经溢出了。 <blockquote> <p>jmap:导出堆文件分析</p> </blockquote> 我们继续用上面代码做测试,并且通过设置参数-Xms20m -Xmx20m设置堆内存大小为20M,通过设置参数-XX:+HeapDumpOnOutOfMemoryError让虚拟机在发生内存溢出时将当前的堆内存转存为快照,方面后面对堆内存做分析,甚至可以找出堆内存泄露的原因。还需要用到一款内存分析工具MAT(Memory Analyzer Tool),是一个功能强大、可视化的Java heap内存分析工具,它可以帮助我们分析Java堆内存泄漏和内存消耗的情况。使用MAT内存分析工具对堆内存的使用情况进行分析,堆内存中各个对象的占用内存大小及各个对象的数量一清二楚的,看看是哪个存活的对象阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成内存泄露的对象,从而再去找出内存泄露的代码。<br /> <br /> <br /> 待验证后继续更新。。。<br />