rainit2006 / My_AWS-Cloud

0 stars 0 forks source link

Spring #7

Open rainit2006 opened 7 years ago

rainit2006 commented 7 years ago

-- 学视频教程 https://www.youtube.com/watch?v=8QA5F0fk6aE

Spring MVC 4 + Hibernate 5 integration example https://www.boraji.com/spring-4-mvc-hibernate-5-integration-example

rainit2006 commented 7 years ago

■参照サイト

Sping横跨了Web层,业务层,DAO层,持久层。可以控制各个层的组件(bean),并维护各个组件之间的关系。

快速入门步骤:

  1. 引入spring的开发包(最小配置spring.jar, 该包包括了常用的jar包; 日志包 common-logging.jar; )
  2. 创建spring的一个核心文件: ApplicationContext.xml . 该文件一般放在src目录下。 (Hibernate有核心文件:Hibernate.cfg.xml; Struts有核心文件:Struts-config.xml) 该文件中引入xsd文件(定义schema)。 ※実際プロジェクトの中、ApplicationContext.xmlはよく「Beans.xml」という名前で利用されている。

3。在 ApplicationContext.xml 文件里配置bean。指定bean的id(相当于程序运行时创建的实例名称),路径,class,属性(Property。属性是一个class时可以引用在ApplicationContext.xml 文件里已声明的id。即“bean的引用”)。 Spring在加载时会自动创建这些bean对象,并放入内存(相当于一个HashMap或HashTable存储这些bean对象)。 对应的说,bean里必须实现这些Property的set方法。 4。在Main函数里调用

ApplicationContext ac=new ClassPathXmlApplicationContext("");  //默认路径是在src目录下。
UserService us = (UserService) ac.getBean("Bean的id");
us.sayHello();  //可以打印出ApplicationContext.xml 文件里配置的名称了。这个叫“属性注入”

可以看出: (1) 没有new对象了,交给spring处理了 (2)上述代码里没有调用Name属性的set方法,但是仍然可以输出Name属性值。


IOC: 控制反转 Inverse of Control。即把创建bean对象和维护bean对象关系的权利(控制权利)从程序中转移到Spring里(ApplicationContext.xml). 传统的代码里,创建bean对象和维护bean对象关系是在程序代码里实现的。

DI (Dependency Injection): 依赖注入。

本质上,IOC和DI是同一个概念。Spring的设计者认为DI更能表达Spring的特性。

达到“解耦”

Spring开发提倡接口編程。 InterfaceClass us = (InterfaceClass) ac.getBean("Bean的id"); それで、Interfaceを継承するクラスはApplicationContext.xmlで切り替える(プログラムコードは変更不要)ことが可能になる。

rainit2006 commented 7 years ago

ApplicationContext.xml中のBeanの取得方法: 1. BeanFactory

  1. ApplicationContext (反射机制)

ApplicationContext容器: 如果bean是singleton,则ApplicationContext.xml里的Bean会被自动创建。默认是singleton。 如果声明是prototypes类型,则不会自动创建。 (Bean的作用域: singleton,prototypes, request, session, global session ) 缺点:耗内存

BeanFactory容器:

BeanFactory factory = new XmlBeanFactory(new ClassResource("com/hsp/ioc/beans.xml"));
factory.getBean("bean的id");

仅仅实例化容器时,bean不会被创建。只有当使用getBean取得某个class对象时,才会被创建。 缺点:速度慢

实际上大多数项目工程里使用ApplicationContext方式,毕竟内存因素影响很小(价格便宜)。

ApplicationContext容器使用方法,有下面三种形式: 1,ClassPathXmlApplicationContext:从类路径中加载

  1. FileSystemXmlApplicationContext: 从文件系统中加载
  2. XmlWebApplicationContext: 从Web系统中加载
rainit2006 commented 7 years ago

官方文档: https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc

Spring2.5引入注解式处理器 @Controller:用于标识是处理器类; @RequestMapping:请求到处理器功能方法的映射规则; @RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定; @ModelAttribute:请求参数到命令对象的绑定; @SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中; @InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;

Spring3.0引入RESTful架构风格支持(通过@PathVariable注解和一些其他特性支持),且又引入了更多的注解支持 @CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定; @RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定;@RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换);@ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换); @ResponseStatus:定义处理器功能处理方法/异常处理器返回的状态码和原因; @ExceptionHandler:注解式声明异常处理器; @PathVariable:请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定


■@ModelAttribute http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation @ModelAttribute can be used either as a method parameter or at the method level.

  1. At the Method Level indicates the purpose of that method is to add one or more model attributes. Such methods support the same argument types as @RequestMapping methods but that cannot be mapped directly to requests.
@ModelAttribute
public void addAttributes(Model model) {
    model.addAttribute("msg", "Welcome to the Netherlands!");
}

In the example, we show a method that adds an attribute named msg to all models defined in the controller class.

In general, Spring-MVC will always make a call first to that method, before it calls any request handler methods. That is, @ModelAttribute methods are invoked before the controller methods annotated with @RequestMapping are invoked. The logic behind the sequence is that, the model object has to be created before any processing starts inside the controller methods.

.2 As a Method Argument When used as a method argument, it indicates the argument should be retrieved from the model.

@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public String submit(@ModelAttribute("employee") Employee employee) {
    // Code that uses the employee object

    return "employeeView";
}

The employee model attribute is populated with data from a form submitted to the addEmployee endpoint. Spring MVC does this behind the scenes before invoking the submit method:

◆ Form Example

: ```  ★ Name Id ``` ``` @Controller @ControllerAdvice public class EmployeeController { private Map employeeMap = new HashMap<>(); @RequestMapping(value = "/addEmployee", method = RequestMethod.POST) public String submit( @ModelAttribute("employee") Employee employee, ★ BindingResult result, ModelMap model) { if (result.hasErrors()) { return "error"; } model.addAttribute("name", employee.getName()); model.addAttribute("id", employee.getId()); employeeMap.put(employee.getId(), employee); return "employeeView"; } @ModelAttribute ★先调用这个 public void addAttributes(Model model) { model.addAttribute("msg", "Welcome to the Netherlands!"); } } ``` In the submit() method we have an Employee object bound to our View. Can you see the power of this annotation? You can map your form fields to an object model as simply as that. In the method we are fetching values from the form and setting them to ModelMap. The @ControllerAdvice assists a controller and in particular, @ModelAttribute methods that apply to all @RequestMapping methods. Of course, our addAttributes() method will be the very first to run, prior to the rest of the @RequestMapping methods. ``` @XmlRootElement public class Employee { private long id; private String name; public Employee(long id, String name) { this.id = id; this.name = name; } // standard getters and setters removed } ``` ```

${msg}

Name : ${name} ID : ${id} ```
rainit2006 commented 7 years ago

Spring Bean的生命周期 http://www.cnblogs.com/zrtqsk/p/3735273.html

Bean装配 http://www.jianshu.com/p/f64dcfb534cc Spring容器提供了两种配置Bean的方式,其一是使用XML文件作为配置文件,其二是基于Java注解的配置方式。

<bean id="sonnet29" class="com.springinaction.springidol.Sonnet29"></bean>

<bean id="poeticDuke" class="com.springinaction.springidol.PoeticJuggler">
    <constructor-arg value="15" />
    <constructor-arg ref="sonnet29" />
</bean>

可以为Bean定义初始化和销毁操作,只需使用init-method和destroy-method参数来配置标签即可。

<bean id="auditorium" class="com.springinaction.springidol.Auditorium"
    init-method="turnOnLights" destroy-method="turnOffLights" />

注入内部Bean

<bean id="kenny" class="com.springinaction.springidol.Instrumentalist">
    <property name="song" value="Happy" />
    <property name="instrument">
        <bean class="com.springinaction.springidol.Saxophone" />
    </property>
</bean>

集合元素 用途

装配list类型的数据,允许重复 装配set类型的数据,不允许重复 装配map类型的数据,key和value可以是任意类型 装配properties类型的数据,key和value必须是String类型 ``` ``` 使用表达式装配 SpEL表达式
rainit2006 commented 7 years ago

AOP 面向切面(方面)编程,是对所有对象或者是一类对象编程。 核心是两个字: 不(在不增加代码的基础上,还增加功能),还()

场景: 共同的功能(切面)比如:事务,日志,安全

概念: 切面(aspect),连接点(joinpoint),通知(advice),切入点(pointcut),连接点,引入

aop编程在框架本身用的很多。

通知(advice):实现共通的类。 一共有5种通知 :Around(拦截目标方法),Before(在目标方法前调用),After,Throws,引入通知(自定义切入点)

代理对象(ProxyFactoryBeans 类):代理接口,完成代理任务。 (织入) 该对象只需配置,不要编写代码。 用到了动态代理技术。

image

■AOP实现的一个例子1: 事先准备下面的类,实现了MethodBeforeAdvice接口(前置增强): image

定义接口

TestServiceInterface{ sayHell();}
TestServiceInterface2{ sayBey();}

在Beans.xml里配置:

1. 被代理的对象
<bean id = "test1Service" class="Test1Service"></bean>
2. 配置前置通知
<bean id="" class="MyMethodBeforeAdvice">    该class继承MethodBeforeAdvice接口
3. 代理对象
<bean id= "proxyFactoryBean" class="proxyFactoryBean">
 -- 代理接口集
<property name="ProxyInterfaces">
<list> 
    <value>com.hanshunping.aop.TestServiceInterface</value>
    <value>com.hanshunping.aop.TestServiceInterface2</value>  //支持代理多个接口
</list>
//////////////
当程序运行时,Spring内部肯定会创建一个proxyFactoryBean implement TestServiceInterface,TestServiceInterface2。来实现list里列举的接口。
/////////////
</property>
 -- 通知织入到代理对象。可以把通知看成拦截器。structs2核心也有拦截器
<property name="interceptorNames">
<value>MyMethodBeforeAdvice</value>
</property>
 --- 配置被代理对象
<property name ="target" ref="test1Service"></property>
<bean>   //--- 对应3.里的<bean>

在App代码里

TestServiceInterface ts = (TestServiceInterface) ac.getBean("proxyFactoryBean"); //注意这里要get代理对象。
ts.syaHello();
((TestServiceInterface2)ts).sayBye(); //此时因为调用的是代理对象,所以前置通知会被注入,结果是MyMethodBeforeAdvice里的函数会被自动调用。

例2 首先我们得有一个所谓的切面类(Aspect):Transaction,我们想达到的目的就是在一个某个业务类的(切入点)execute方法调用之前,执行Transaction.beginTx()方法,在调用之后,需要执行Transaction.commitTx()方法。 当然,想描述这些规则, xml依然是不二之选: image 注意:现在Transaction这个类和业务类在源代码层次上没有一点关系,完全隔离了。


■AOP实现的一个例子2:@AspectJ配置切面 先用@AspectJ定义一个切面:

package test.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class PreAspect {
    @Before("execution(* shout(..))")//意思是返回值任意 参数任意
    public void beforeShout()
    {
        System.out.println("准备叫");
    }
}

在applicationContext.xml中设置:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop" ★
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">★

<!--基于@AspectJ切面的驱动器-->
<aop:aspectj-autoproxy/>
<bean class="test.aop.PreAspect" />
<bean class="test.aop.ChinaDog" id="chinaDog"/>

在AopTest.java中进行测试

public static void main(String[] args)
{
    ApplicationContext ac = new FileSystemXmlApplicationContext("web/WEB-INF/applicationContext.xml");
    Dog dog = (Dog)ac.getBean("chinaDog");    //注意这里调用的是chinaDog
    dog.shout("jim");  //在shout方法调用前会调用PreAspect类的beforeShout方法。
    dog.sleep("tom");
}

■AOP实现的一个例子3:使用Spring来定义纯粹的POJO切面 使用spring的aop标签

<!-- POJO -->
<bean class="test.aop.PreAspect" id="preAspect" />
<bean class="test.aop.ChinaDog" id="chinaDog"/>
<aop:config>
       <aop:aspect ref="preAspect">
              <aop:before method="beforeShout" pointcut="execution(* *.shout(..))"/>
       </aop:aspect>
</aop:config>

JAVAコード

public static void main(String[] args)
{
    ApplicationContext ac = new FileSystemXmlApplicationContext("web/WEB-INF/applicationContext.xml");
    Dog dog = (Dog)ac.getBean("chinaDog");//注意这里调用的是chinaDog
    dog.shout("jim");
    dog.sleep("tom");
}
rainit2006 commented 7 years ago

SSH (Spring + Struct + Hibernate) 创建一个雇员薪资系统 薪资系统架构: 界面 --<接口 EmployeeServiceInterface>-- 业务操作层 ---- 持久层(hibernate) ---- 数据库

创建手顺: 1,先搞定spring:创建一个新Project 2,引入spring开发包。拷贝到reference lib下。 3,编写 applicationContext.xml (or Beans.xml)文件,并放在 src目录下。 4,测试一下spring是否ok 5,加入Hibernate开发包 6,Hibernate里面的核心要被spring接管 (1) 在 beans.xml里配置数据源(dataSource):driverClassName, url(数据库地址), username(数据库访问名称), password, inintialSize(连接池启动时的初始值), maxActive(连接池得最大值), maxIdle(最大空闲值), minIdle(最小空闲值) (2)配置sessionFactory对象:dataSource,mappingResources(Hiberate里的对象映射。本例里指定下面第8步创建的“Employee.hbm.xml”文件),hibernateProperties。

  1. 创建java package(Employee.java):包含id,name,email,hiredate,salary
  2. 创建Employee.hbm.xml,设定hibernate-mapping
    <hibernate-mapping>
      <class name="Employee" table="employee">
             <id name="id" type="java.lang.Interger">
             <generator class="native" />
             </id>
             <property name="email" type="java.lang.String">
             <column name="email" length="64">
             </property>
             <property name="hiredate" type="java.util.Date">
             <column name="hiredate" >
             </property>
             <property name="name" type="java.lang.String">
             <column name="name" length="64">
            </property> 
            <property name="salary" type="java.lang.Float">
             <column name="salary">
             </property>
      </class>
    </hibernate>

    9, 测试spring和hibernate是否可以结合使用 10,创建web层和业务层之间的接口(EmployeeServiceInter),声明方法:addEmployee, showEmployee, updateEmployee, delEmployee.

创建EmployeeService来实现上述接口。 而且在addEmployee等函数里都涉及到session操作,这些session操作可以通过AOP事务管理来实现。

11,在beans.xml里配置EmployeeService对象

引用了hibernate里的sessionFactory属性。 在beans.xml里配置事务管理器,统一管理sessionFactory的事务。 `指定: id="txManager" class="hibernate3.HibernateTransactionManager"` 启用事物注解 `指定: ` 在EmployeeServer class前加上语句: `@Transsactional //目的是为了让spring的事务管理器接管该server的所有事务` 12,在EmployeeService里通过sessionFactory得到session,进行数据源的操作。 13, main函数里实现 ``` EmployeeServiceInter employeeServiceInter = .... employeeServiceInter.addEmployee(employee); ```
rainit2006 commented 7 years ago

14, 整合struts (1)引入struts的安装包 (2) 创建jsp页面, actionForm类 (3)创建struts-config.xml ,放在WEB-INF目录下

(4) 让 spring管理structs(action控件) 在struct-config.xml文件理添加下面代码,这样当action发生时(例:login.do -> web服务器),ActionServlet(总司令)会通过spring找对应的action的配置。

     <controller>
           <set-property property="processorClass" value="org.springframework.web.struts.DelegationRequestProcessor">
   </controller>

在beans.xml里配置action路径

rainit2006 commented 6 years ago

SpringMVC

■SpringMVC详细运行流程图 image

■フォルダ・ファイル構成 image

■DispatcherServlet Spring Web 模型-视图-控制(MVC)框架是围绕 DispatcherServlet 设计的,DispatcherServlet 用来处理所有的 HTTP 请求和响应。Spring Web MVC DispatcherServlet 的请求处理的工作流程如下图所示: image

下面是对应于 DispatcherServlet 传入 HTTP 请求的事件序列:

  1. 收到一个 HTTP 请求后,DispatcherServlet 根据 HandlerMapping 来选择并且调用适当的控制器。
  2. 控制器接受请求,并基于使用的 GET 或 POST 方法来调用适当的 service 方法。Service 方法将设置基于定义的业务逻辑的模型数据,并返回视图名称到 DispatcherServlet 中。 3.DispatcherServlet 会从 ViewResolver 获取帮助,为请求检取定义视图。 4.一旦确定视图,DispatcherServlet 将把模型数据传递给视图,最后呈现在浏览器中。

你需要映射你想让 DispatcherServlet 处理的请求,通过使用在 web.xml 文件中的一个 URL 映射。

■org.springframework.web.servlet.DispatcherServlet について 普通のWEBアプリケーションではServletを作成しますが、Spring Web MVCでは作成せず、Springが用意してくれている org.springframework.web.servlet.DispatcherServletを使用します。

DispatcherServletがクライアントからの要求を受け付けて、コントローラクラス(@Controller)に割り振って、コントローラクラス からの戻りからビュー(jsp)を割り振ってクライアントに戻して・・・などSpring MVCの全体コントロールを行いますが、ソースや 設定ファイル上で登場するのは、このweb.xmlだけです。

■POM.xml 在pom.xml中自定义变量及其使用 背景: 类似于版本号,可能一个组件中的多个jar包都是采用同一版本号,当要升级组件时就需要逐一修改组件中每个jar的版本号,比较繁琐而且容易漏掉,我们可以自定义一个版本号变量,然后组件中的jar包统一调用这个变量即可。

标签下自定义变量

<properties>  
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    <jetty.version>9.3.14.v20161028</jetty.version>  
    <spring.version>4.1.3.RELEASE</spring.version>  
    <solr.version>6.3.0</solr.version>  
</properties>  

变量的调用:

<dependency>  
    <groupId>org.apache.solr</groupId>  
    <artifactId>solr-solrj</artifactId>  
    <version>${solr.version}</version>  
</dependency> 

■Web.xml Sample

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">
    <display-name>springMVC</display-name>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcherServlet</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>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

最初に org.springframework.web.context.ContextLoaderListener クラスをリスナー登録しています。 これが登録されていることにより、Spring設定ファイル(/WEB-INF/applicationContext.xml)を読みに行きます。 このパスやファイル名称はcontextConfigLocationで変更することが出来ます。

サーブレットの設定は、次の通り。

  <servlet>
    <servlet-name>[プロジェクト名]</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>[プロジェクト名]</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

如果遇到匹配*.htm的URL,会使用org.springframework.web.servlet.DispatcherServlet来处理。

■/WEB-INF/spring/app.xmlに変更

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/app.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

Spring設定ファイルはサーブレット毎に設定出来ます。設定する場合は init-param 内の contextConfigLocation で設定します。

■サーブレットに/WEB-INF/spring/mvc-servlet.xmlに適用

<servlet> 
  <!-- 配置DispatcherServlet -->
  <servlet-name>springMvc</servlet-name> 
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <!-- 指定spring mvc配置文件位置 不指定使用默认情况 -->
    <init-param>   
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring/mvc-servlet.xml</param-value>
    </init-param> 
  <!-- 设置启动顺序 -->
  <load-on-startup>1</load-on-startup> 
</servlet>

<!-- ServLet 匹配映射 -->
<servlet-mapping>
  <servlet-name>springMvc</servlet-name>
  <url-pattern>*.zxh</url-pattern>
</servlet-mapping>

○需要搞清楚classpath是什么,以及classpath:和classpath有何区别: 首先 classpath是指 WEB-INF文件夹下的classes目录 classpath 和 classpath 区别: classpath:只会到你的class路径中查找找文件; classpath:不仅包含class路径,还包括jar文件中(class路径)进行查找.

■Filter サーブレット・フィルタを使用して、Webアプリケーション・リクエストの前処理やサーバー・レスポンスの後処理を実行できます。

下図は左側が、リクエスト対象のサーブレットに対してフィルタが構成されていない例を示しています。右側の例では、複数のフィルタ(1、2、...、N)が構成されています。 image

各フィルタは、javax.servlet.FilterインタフェースとdoFilter()メソッドを実装します。 void doFilter(ServletRequest request,  ServletResponse response,  FilterChain chain) フィルタ・チェーンは、javax.servlet.FilterChainインタフェースを実装するクラス(サーブレット・コンテナによって提供されます)のインスタンスです。 フィルタ・チェーンは、フィルタの順序を反映します。サーブレット・コンテナは、web.xmlファイルにおける構成順序に基づいて、マップされるフィルタを持つすべてのサーブレットまたはその他のリソースのフィルタ・チェーンを構成します。フィルタ・チェーンに含まれる各フィルタについては、フィルタに渡されるフィルタ・チェーン・オブジェクトが、順番にコールされる残りのフィルタを表します(これらのフィルタの後にターゲット・サーブレットが起動されます)。 FilterChainインタフェースも、doFilter()メソッドを指定します。 void doFilter(ServletRequest request, ServletResponse response)

<filter>
    <filter-name>timer</filter-name>
    <filter-class>filter.TimerFilter</filter-class>
    <init-param> //初期化パラメータ
        <param-name>name</param-name>
        <param-value>value</param-value>
    <init-param>
</filter>
要素およびそのサブ要素を使用して、フィルタ名をサーブレット名またはURLパターンにマップし、フィルタを対応するリソース(サーブレット、JSPページなど)に関連付けます。たとえば、myservletという名前のサーブレットが起動されると必ずフィルタが起動されるようにするには、次のようにします。 ``` timer myservlet ``` spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) ■web.xml 中加载顺序 最终得出结果:先 listener >> filter >> servlet >> spring ■property-placeholder デフォルトでは、以下の順番でプロパティにアクセスする。 実行中のJVMのシステムプロパティ 環境変数 アプリケーション定義のプロパティファイル また、JAVAソースコード中、 [@Value("${key}")]でプロパティファイルを読み込み、keyに紐づく値を変数"value"に設定してくれる。このように${キーの値}という書き方でvalueを取得できると覚えておく。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー その他に、 欢迎页: ``` login.jsp ``` 错误页: ``` java.lang.Throwable /views/error.jsp 500 /views/500.jsp 404 /views/404.jsp ```
rainit2006 commented 6 years ago

ApplicationContext.xmlファイルの記述方法 <beanの取得方法> XMLで記述したbeanは、getBean()で簡単に取得できます。

FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("c:/test/context.xml");
DataSource ds = (DataSource)context.getBean("dataSource");
<?xml version="1.0" encoding="UTF-8"?>
<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="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
      <property name="driverClassName" value="org.postgresql.Driver"/>
      <property name="url" value="jdbc:postgresql://localhost/sample?useUnicode=true&amp;characterEncoding=utf-8" />
      <property name="maxActive" value="10" />
      <property name="username" value="XXX" />
      <property name="password" value="XXX" />
   </bean>
   <bean id="memberDao" class="my.MemberDao" >
      <property name="dataSource" ref="dataSource"/>
   </bean>
</beans>

<beanタグ、propertyタグについて> beanタグは属性をいくつか持っています。destroy-method属性は、DIコンテナが終了するときに実行されるメソッドで、記述されたメソッド(上記ではclose())が実行されます。   beanタグは、propertyタグを持つことができます。   俗に言うJavaクラスのsetterに当たるもので、上記は例えば以下のような動作と全く同じになります。

dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost/sample?useUnicode=true&amp;characterEncoding=utf-8");
dataSource.setMaxActive(10);
   :

!!引数の型が違うことにも注目してください。!! Springの設定ファイルには文字列、数字の違いが表れていません。3つとも""で括られているだけです。 では、どうやって文字列に変換する、数字に変換する、といった判断をしているのでしょうか? それは、Springが指定のクラスのsetterの型を見て、自動で変換しているのです。 ですのでSpringが知らない型があると当然変換できません。自作の変換クラスを作成して設定することもできますが、通常はサンプルのmemberDaoのようにします。 ref という属性が使用されています。 ref はDIコンテナ内に設定された他のbeanを参照するためのものです。(もちろん参照先のdataSourceというbeanはXMLに記述しなければなりません)

<beanタグのidについて> idは、Spring設定ファイル内で一意でなくてはなりません。

■beanの生成パターン(singleton, prototypeなど) image

■beanの生成タイミング(lazy-init) <bean id="member" class="my.Member" lazy-init="true" /> image

■bean設定の引継ぎ(abstract)   実は、beanのプロパティなどを上書きすることができます。   ですので、同じような設定をする場合、親beanを指定すれば、記述の省略ができます。

<!-- 引継ぎ元(親) -->
<bean id="memAbstarct" class="my.MemberDao" abstract="true" >
  <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 単純に引き継いだ例。dataSourceが引き継がれています -->
<bean id="memberDao1" parent="memAbstarct" >
  <property name="switch" value="1"/>
</bean>

■beanの設定のオーバーライド(上書き) XML内から他のファイルをimportすることができます。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
">
 <import resource="classpath:my/spring/base-context.xml"/>
</beans>

importで指定したファイル内に同じidが存在すれば、importしたファイルのbeanが上書きされます。

■コンストラクタの指定(constructor-arg) 1.引数の数と型で指定する方法

 <bean class="com.my.MyClass">
   <constructor-arg index="0"  value="あいう" />
   <constructor-arg index="1"  value="12" />
</bean>

2.引数の名前で指定する方法 【ApplicationContextファイル】

<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg name="years" value="7500000"/>
  <constructor-arg name="ultimateanswer" value="42"/>
</bean>

コード中

@ConstructorProperties({"years", "ultimateAnswer"})
public ExampleBean(int years, String ultimateAnswer) {
   this.years = years;
   this.ultimateAnswer = ultimateAnswer;
}

ーーーーーーーーーーーーー tx:annotation-driven と mvc:annotation-driven 其含义就是支持注解,一般根据前缀 tx、mvc 等也能很直白的理解出来分别的作用。 就是支持事务注解的(@Transactional) 、

就是支持mvc注解的,说白了就是使Controller中可以使用MVC的各种注解。 首先, 会有一个属性来指定使用哪个事务管理器,如:。 然后事务管理器 transactionManager 会引用 dataSource (如果我们使用JPA或Hibernate,也需要指定一个 entityManagerFactory ),dataSouce 肯定就是直接对数据库的了。 这样逐层引用下去,所以我们使用@Transactionl 注解可以控制事务就通俗易懂了。 **@RestController**和**@RequestMapping** Spring WebMvc框架会将Servlet容器里收到的HTTP请求根据路径分发给对应的@Controller类进行处理,@RestController是一类特殊的@Controller,它的返回值直接作为HTTP Response的Body部分返回给浏览器。 @RequestMapping注解表明该方法处理那些URL对应的HTTP请求,也就是我们常说的URL路由(routing),请求的分发工作是有Spring完成的。 ``` @RestController @RequestMapping("/classPath") public class Application { @RequestMapping("/methodPath") public String method() { return "mapping url is /classPath/methodPath"; } } ``` ``` @RequestMapping("/users/{username}") public String userProfile(@PathVariable("username") String username) { return String.format("user %s", username); } @RequestMapping("/posts/{id}") public String post(@PathVariable("id") int id) { return String.format("post %d", id); } ```
rainit2006 commented 6 years ago

Difference between applicationContext.xml and spring-servlet.xml in Spring Framework

In most simple cases, the applicationContext.xml context is unnecessary. It is generally used to contain beans that are shared between all servlets in a webapp. If you only have one servlet, then there's not really much point, unless you have a specific use for it.

rainit2006 commented 6 years ago

Hibernate

JDBC http://wiki.jikexueyuan.com/project/hibernate/orm-overview.html JDBC 代表 Java Database Connectivity ,它是提供了一组 Java API 来访问关系数据库的 Java 程序。这些 Java APIs 可以使 Java 应用程序执行 SQL 语句,能够与任何符合 SQL 规范的数据库进行交互。 JDBC 提供了一个灵活的框架来编写操作数据库的独立的应用程序,该程序能够运行在不同的平台上且不需修改,能够与不同的 DBMS 进行交互。 image

ORM ORM 表示 Object-Relational Mapping (ORM),是一个方便在关系数据库和类似于 Java, C# 等面向对象的编程语言中转换数据的技术。

Hibernate Hibernate 是传统 Java 对象和数据库服务器之间的桥梁,用来处理基于 O/R 映射机制和模式的那些对象。 image Hibernate 优势

  1. Hibernate 使用 XML 文件来处理映射 Java 类别到数据库表格中,并且不用编写任何代码。
  2. 为在数据库中直接储存和检索 Java 对象提供简单的 APIs。
  3. 如果在数据库中或任何其它表格中出现变化,那么仅需要改变 XML 文件属性
  4. 抽象不熟悉的 SQL 类型,并为我们提供工作中所熟悉的 Java 对象。
  5. Hibernate 不需要应用程序服务器来操作。
  6. 操控你数据库中对象复杂的关联。
  7. 最小化与访问数据库的智能提取策略。
  8. 提供简单的数据询问。

Hibernate架构 image 更详细些: image

配置对象:配置对象是你在任何 Hibernate 应用程序中创造的第一个 Hibernate 对象,并且经常只在应用程序初始化期间创造。它代表了 Hibernate 所需一个配置或属性文件。配置对象提供了两种基础组件。

SessionFactory 对象:配置对象被用于创造一个 SessionFactory 对象,使用提供的配置文件为应用程序依次配置 Hibernate,并允许实例化一个会话对象。SessionFactory 是一个线程安全对象并由应用程序所有的线程所使用。

Session 对象:一个会话被用于与数据库的物理连接。Session 对象是轻量级的,并被设计为每次实例化都需要与数据库的交互。持久对象通过 Session 对象保存和检索。

Transaction 对象:一个事务代表了与数据库工作的一个单元并且大部分 RDBMS 支持事务功能。在 Hibernate 中事务由底层事务管理器和事务(来自 JDBC 或者 JTA)处理。

Query 对象:Query 对象使用 SQL 或者 Hibernate 查询语言(HQL)字符串在数据库中来检索数据并创造对象。一个查询的实例被用于连结查询参数,限制由查询返回的结果数量,并最终执行查询。

Criteria 对象:Criteria 对象被用于创造和执行面向规则查询的对象来检索对象。


持久化类 在 Hibernate 中,其对象或实例将会被存储在数据库表单中的 Java 类被称为持久化类。若该类遵循一些简单的规则或者被大家所熟知的 Plain Old Java Object (POJO) 编程模型,Hibernate 将会处于其最佳运行状态。 以下所列就是持久化类的主要规则,然而,在这些规则中,没有一条是硬性要求。

映射文件 一个对象/关系型映射一般定义在 XML 文件中。映射文件指示 Hibernate 如何将已经定义的类或类组与数据库中的表对应起来。 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   <class name="Employee" table="EMPLOYEE">
      <meta attribute="class-description">
         This class contains the employee detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="native"/>
      </id>
      <property name="firstName" column="first_name" type="string"/>
      <property name="lastName" column="last_name" type="string"/>
      <property name="salary" column="salary" type="int"/>
   </class>
</hibernate-mapping>

需要以格式 .hbm.xml保存映射文件。我们保存映射文件在 Employee.hbm.xml 中。 在映射文件中使用的一些标签:

映射类型 Java类型和 Table类型之间的 映射关系 http://wiki.jikexueyuan.com/project/hibernate/mapping-types.html

rainit2006 commented 6 years ago

Spring Security允许我们在定义URL访问或方法访问所应有的权限时使用Spring EL表达式,在定义所需的访问权限时如果对应的表达式返回结果为true则表示拥有对应的权限,反之则无。 image

  1. 通过表达式控制URL权限
    
    <security:http use-expressions="true">
      <security:form-login/>
      <security:logout/>
      <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
    </security:http>
在上述配置中我们定义了只有拥有ROLE_USER角色的用户才能访问系统。

2.通过表达式控制方法权限
2.1使用@PreAuthorize和@PostAuthorize进行访问控制
@PreAuthorize可以用来控制一个方法是否能够被调用。
`  @PreAuthorize("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')") `

/**

}

有时候可能你会想在方法调用完之后进行权限检查,这种情况比较少,但是如果你有的话,Spring Security也为我们提供了支持,通过@PostAuthorize可以达到这一效果。

@PostAuthorize("returnObject.id%2==0") public User find(int id) { User user = new User(); user.setId(id); return user; }

       上面这一段代码表示将在方法find()调用完成后进行权限检查,如果返回值的id是偶数则表示校验通过,否则表示校验失败,将抛出AccessDeniedException。       需要注意的是@PostAuthorize是在方法调用完成后进行权限检查,它不能控制方法是否能被调用,只能在方法调用完成后检查权限决定是否要抛出AccessDeniedException。

2.2使用@PreFilter和@PostFilter进行过滤
使用@PreFilter和@PostFilter可以对集合类型的参数或返回值进行过滤。使用@PreFilter和@PostFilter时,Spring Security将移除使对应表达式的结果为false的元素。

@PostFilter("filterObject.id%2==0") public List findAll() { List userList = new ArrayList(); User user; for (int i=0; i<10; i++) { user = new User(); user.setId(i); userList.add(user); } return userList; }

上述代码表示将对返回结果中id不为偶数的user进行移除。filterObject是使用@PreFilter和@PostFilter时的一个内置表达式,表示集合中的当前对象。

当@PreFilter标注的方法拥有多个集合类型的参数时,需要通过@PreFilter的filterTarget属性指定当前@PreFilter是针对哪个参数进行过滤的。如下面代码就通过filterTarget指定了当前@PreFilter是用来过滤参数ids的。

@PreFilter(filterTarget="ids", value="filterObject%2==0") public void delete(List ids, List usernames) { ... }



3     使用hasPermission表达式
http://elim.iteye.com/blog/2247073
rainit2006 commented 6 years ago

http://www.codeceo.com/article/spring-transactions.html http://www.cnblogs.com/xiohao/p/4808088.html @Transactional注解管理事务 ■什么是“事务”? 事务是一组操作的原子执行,其中任何一笔操作失败将导致全部操作撤销。 事务遵循ACID原则。 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。

■对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 1,获取连接 Connection con = DriverManager.getConnection() 2,开启事务con.setAutoCommit(true/false); 3,执行CRUD 4,提交事务/回滚事务 con.commit() / con.rollback(); 5,关闭连接 conn.close(); 使用Spring的事务管理功能后,我们可以不再写步骤 2 和 4 的代码,而是由Spirng 自动完成。

■Spring 事务的传播属性 就是定义在存在多个事务同时存在的时候,spring应该如何处理这些事务的行为。

PROPAGATION_REQUIRED : 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是 Spring 默认的事务的传播。 PROPAGATION_REQUIRES_NEW :新建事务,如果当前存在事务,把当前事务挂起。新建的事务将和被挂起的事务没有任何关系,是两个独立的事务,外层事务失败回滚之后,不能回滚内层事务执行的结果,内层事务失败抛出异常,外层事务捕获,也可以不处理回滚操作。 などなど

■数据库隔离级别 image 脏读:一事务对数据进行了增删改,但未提交,另一事务可以读取到未提交的数据。如果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。 不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外一个事务对数据进行了修改,这时候两次读取的数据是不一致的。 幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数据,这时候第一个事务就会丢失对新增数据的修改。

总结: 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。 大多数的数据库默认隔离级别为 Read Commited,比如 SqlServer、Oracle 少数数据库默认隔离级别为:Repeatable Read 比如: MySQL InnoDB

■Spring中的隔离级别 image

■Spring 事务管理分为编码式和声明式的两种方式。 编程式事务指的是通过编码方式实现事务; 声明式事务基于 AOP,将具体业务逻辑与事务处理解耦。声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中声明式事务用的比较多。

■ 使用@Transactional 注解管理事务的实现步骤分为两步。第一步,在 xml 配置文件中添加如清单 1 的事务配置信息。除了用配置文件的方式,@EnableTransactionManagement 注解也可以启用事务管理功能。这里以简单的 DataSourceTransactionManager 为例。

清单 1. 在 xml 配置中的事务配置信息

<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

或者

<!-- 事务管理器配置,单数据源事务 -->
    <bean id="pkgouTransactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="pkGouDataSource" />
    </bean>
<!-- 使用annotation定义事务 -->
    <tx:annotation-driven transaction-manager="pkgouTransactionManager" />

第二步,将@Transactional 注解添加到合适的方法上,并设置合适的属性信息。 比如在使用事务的方法或者类上添加 @Transactional(“pkgouTransactionManager”)注解。

rainit2006 commented 6 years ago

Spring的注解 @Service用于标注业务层组件(我们通常定义的service层就用这个) @Controller用于标注控制层组件(如struts中的action) @Repository用于标注数据访问组件,即DAO组件 @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

这几个注解是当你需要定义某个类为一个bean,则在这个类的类名前一行使用@Service("XXX"),就相当于讲这个类定义为一个bean,bean名称为XXX; 这几个是基于类的,我们可以定义名称,也可以不定义,不定义会默认以类名为bean的名称(类首字母小写)。 下面这4个BeanPostProcessor的作用,就是为了你的系统能够识别相应的注解。 AutowiredAnnotationBeanPostProcessor CommonAnnotationBeanPostProcessor PersistenceAnnotationBeanPostProcessor RequiredAnnotationBeanPostProcessor 如果你想使用@Autowired注解,那么就必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。传统声明方式如下 <bean class="org.springframework.beans.factory.annotation. AutowiredAnnotationBeanPostProcessor "/> 于是spring给我们提供的简化配置方式,自动帮你完成声明。

@Required:应用于 bean 属性的 setter 方法。 @Autowired :apply to bean property setter methods, non-setter methods, constructor and properties。 @Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier 使用;

不使用@Autowired的话:

public class Boss
{   
    private Car car;   
    private Office office;   

     ★这里有Car和Officce的setter 代码★

    @Override  
    public String toString()
    {   
        return "car:" + car + "/n" + "office:" + office;   
    }   
}   

<?xml version="1.0" encoding="UTF-8" ?>   
<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="boss" class="Boss">   
        <property name="car" ref="car"/>     //★需要声明car和office的property★
        <property name="office" ref="office" />   
    </bean>   
    <bean id="office" class="Office">   
        <property name="officeNo" value="002"/>   
    </bean>   
    <bean id="car" class="Car" scope="singleton">   
        <property name="brand" value="红旗CA72"/>   
        <property name="price" value="2000"/>   
    </bean>   
</beans>

使用@Autowired的话可以消除消除set方法:

import org.springframework.beans.factory.annotation.Autowired;   
public class Boss
{   
    @Autowired  
    private Car car;   
    @Autowired  
    private Office office;   
} 

<?xml version="1.0" encoding="UTF-8" ?>   
<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">   

    <!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->   
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>   

    <!-- 移除 boss Bean 的属性注入配置的信息 -->   
    <bean id="boss" class="Boss"/>   

    <bean id="office" class="Office">   
        <property name="officeNo" value="001"/>   
    </bean>   
    <bean id="car" class="Car" scope="singleton">   
        <property name="brand" value="红旗 CA72"/>   
        <property name="price" value="2000"/>   
    </bean>   
</beans>

@Autowired默认是按照byType进行注入的,但是当byType方式找到了多个符合的bean,又是怎么处理的?Autowired默认先按byType,如果发现找到多个bean,则又按照byName方式比对,如果还有多个,则报出异常。

rainit2006 commented 6 years ago

Spring MVC ■参照サイト: http://www.jianshu.com/p/21b143ad235b

image

■DataSource 在Spring框架中有如下3种获得DataSource对象的方法: 1.从JNDI获得DataSource. 2.从第三方的连接池获得DataSource. 3.使用DriverManagerDataSource获得DataSource. 一、从JNDI获得DataSource

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">  
<property name="jndiName">  
 <value>java:comp/env/jcptDataSourceJNDI</value>  
</property>  
 </bean>

ここのjcptDataSourceJNDI是tomcat或者其他应用服务器配置的JNDI.

二,从第三方的连接池获得DataSource 三种数据库连接池的配置,使用这些连接池可以获得一个数据源。 1、spring自带的JDBC连接池; 2、c3p0; 3、dbcp;

1,spring自带的JDBC方式 spring提供了对JDBC的支持,且提供了基于JDBC的数据源的配置,如下配置文件

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

2、c3p0 c3p0是一个开源的数据库连接池,可以很好的管理数据连接,如下配置

<bean id="dataSourceC3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

3、dbcp dbcp同样是一个开源的数据连接池,如下配置,

<bean id="dataSourceDbcp" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">        
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
rainit2006 commented 6 years ago

JNDI 図 1. JNDI アーキテクチャー image

■Java使用JNDI配置WEB项目数据源

使用传统的方式

一般对于普通的项目,习惯上使用.properties的文件来配置数据源的一些信息。在.properties文件中配置数据源连接字符串、用户名、密码和驱动的类,然后在代码中读取配置文件的信息再通过DriverManager.getConnection(url, username, password)的方式获取数据源连接对象。

使用JNDI的方式

1、获取数据源的连接对象Connection public static Connection getConnection(String jndi) {   。。。。。。。。 //如果数据源的名称不为空的话使用指定的数据源的名称来获取数据库连接对象 if(StringUtils.isNotEmpty(jndi)) { datasource = (DataSource) envContext.lookup(jndi); } else { datasource = (DataSource) envContext.lookup("sqlserver/default"); } connection = datasource.getConnection();   。。。。 } 2、在Tomcat中的webapp中加入Resource配置

<Resource name="sqlserver/default"
    auth="Container"
    type="javax.sql.DataSource"
    maxActive="100"
    maxIdle="30"
    maxWait="10000"
    username="sa"
    password="*"
    driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
    url="jdbc:sqlserver://localhost:1433;databasename=DBNAME"/>

常见配置属性描述: name:JDBC数据源的名称 auth:认证方式,一般设置为Container,还有一种是Application type:当前配置资源的类别 factory:数据源工厂,默认为”org.apache.commons.dbcp.BasicDataSourceFactory” driverClassName:驱动的全路径类名 maxActive:当前数据源支持的最大并发数 maxIdle:连接池中保留最大数目的闲置连接数 maxWait:当连接池中无连接时的最大等待毫秒数,在等当前设置时间过后还无连接则抛出异常 username:访问数据库的用户名 password:访问数据库的密码 url:JDBC驱动的连接字符串 validationQuery:在返回应用之前,用于校验当前连接是否有效的SQL语句,如果指定了,当前查询语句至少要返回一条记录,可以写成select top 1 * from sysobjects

3、在Tomcat的lib目录下面添加数据库的驱动文件 MySQL:mysql-connector-java-5.1.20-bin.jar SQLServer:sqljdbc4.jar Oracle:ojdbc14.jar

4、在Spring项目的web.xml加入如下配置

<resource-ref>
    <res-ref-name>sqlserver/default</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

注:属于可选配置,如果在web.xml中加入了上面的配置,则需要在Tomcat中一定要配置对应的Resource,否则会报错。 5、使用方式

Connection conn = getConnection("sqlserver/default");
...
rainit2006 commented 6 years ago

■Bean Validation Spring MVCでは、Bean Validation (JSR-303)をサポートしており、アノテーションベースな入力チェックを、簡単に 実装することができる。例として、エコーアプリケーションで名前の入力チェックを行う。 例1

import javax.validation.constraints.NotNull; ★
import javax.validation.constraints.Size; ★

public class EchoForm implements Serializable {
private static final long serialVersionUID = 2557725707095364446L;

    @NotNull // ★@NotNull アノテーションをつけることで、HTTPリクエスト中に name パラメータがあることを確認する。
    @Size(min = 1, max = 5) // ★@Size(min = 1, max = 5) をつけることで、name のサイズが、1以上5以下であることを確認する。
    private String name;

例2

import javax.validation.Valid;★
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult; ★
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("echo")
public class EchoController {

    @ModelAttribute
    public EchoForm setUpEchoForm() {
        EchoForm form = new EchoForm();
        return form;
    }

    @RequestMapping
    public String index(Model model) {
        return "echo/index";
    }

    @RequestMapping("hello")
    public String hello(@Valid EchoForm form, BindingResult result, Model model) { // ★
        if (result.hasErrors()) { // ★
            return "echo/index";
        }
        model.addAttribute("name", form.getName());
        return "echo/hello";
    }
}

コントローラー側には、Validation対象の引数に @Valid アノテーションを付加し、 BindingResult オブジェクトを引数に追加する。 Bean Validationによる入力チェックは、自動で行われる。結果は、 BindingResult オブジェクトに渡される。 hasErrors メソッドを実行して、エラーがあるかどうかを確認できる。

■Hibernateのvalidation http://tech.pjin.jp/blog/2016/06/14/springframework9/

rainit2006 commented 6 years ago

http://blog.sina.com.cn/s/blog_6d3c1ec601014h1h.html Spring mvc视图机制 Spring的控制器Controller会返回一个ModelAndView的实例。Spring根据ModelAndView实例中的View和Model把信息反馈给用户。Spring中的视图是以名字为标识的,ViewResolver是通过名字来解析view的。Spring提供了多种视图和视图解析器。

ModelAndView 它代表了Spring Web MVC中呈现画面时所使用的Model与View,由于Java一次只能返回一个物件,所以ModelAndView的作用封装这两个物件,以方便您一次返回Model与View这两个物件。 ModelAndView(String viewName):最简单的ModelAndView是只有View的名称。

ModelAndView(String viewName, Map model) 如果您要返回呈现画面时所需的Model资料,则可以使用Map来收集呈现View时所需的资料,然后在建构ModelAndView作为建构时的参数。

ModelAndView(String viewName, String modelName, Object modelObject) 返回单个model时使用。