IDEA02 利用Maven創建Web項目、為Web應用添加Spring框架支持、bean的創建於獲取、利用注解配置Bean、自動裝配Bean、MVC配置


 

1 環境版本說明

  Jdk : 1.8

  Maven : 3.5 

  IDEA : 專業版 2017.2

 

2 環境准備

  2.1 Maven安裝及其配置

  2.2 Tomcat安裝及其配置

 

3 詳細步驟

  3.1 根據模板創建maven工程

    file -> new -> project -> maven -> webapp

    技巧01:根據模板創建web工程時,請選擇 maven-archetype-webapp 

  3.2 目錄結構調整

    項目創建成功后的目錄結構如下:

    跳坑01:新創建的項目中沒有存放源文件的java文件夾,也沒有存放測試文件的test文件夾,同樣沒有存放資源文件的resources文件夾

    跳坑01:在main目錄下新建java、resources兩個文件夾,分別用來存放源文件和資源文件;在main的同級目錄中新建test目錄用來存放測試文件夾

    技巧01:雖然我們創建了相關的文件夾,但是IDEA並不知道java文件夾是用來存放源文件,test用來存放測試文件,resources用來存放資源文件的;我們必須進行手動配置:

    說明:是在main的統計目錄中創建一個文件夾名為test,再在test中創建一個java文件夾,並將這個java文件夾指定為存放測試文件的包(本博文是之間將test文件夾指定成了存放測試文件的地方)

      file -> project structure -> modules

    設置完后整個目錄結構如下:

  3.3 配置tomcat

    3.3.1 打開啟動配置頁面

    3.3.2 添加tomcat啟動項

    3.3.3 配置tomcat基本信息

    3.3.4 添加web模塊

      技巧01:為項目添加一個web模塊,file -> project structure -> module 

      跳坑01:利用IDEA創建項目時會在main目錄下創建一個webapp文件夾,該文件夾里面的內容就是需要被部署到tomcat容器的內容,但是我們為項目添加了web模塊后會自動在項目的根目錄下生成一個web文件夾【建議將這個web文件夾刪掉】,這個文件夾的作用和main目錄下的webapp文件夾的作用相同,而且添加web模塊時自動尋找的是新創建的web文件夾下面的web.xml文件;將web.xml改成webapp下面的web.xml,並將web的源文件文件夾改成webapp,修改后的效果如下:

    3.3.5 添加artifacts

      技巧01:添加一個web應用,這個web引用來源於modules【其實就是來源於我們創建的web工程】

    3.3.6 配置發布頁面

      將 artifacts 中配置為web應用添加到tomcat配置中的deployment

 

    3.3.7 配置開發熱部署

      就是修改前后台代碼后不用重啟tomcat,IDEA會自動進行【修改后台時自動重啟tomcat服務器,修改前台時刷新瀏覽器就可以啦】

    3.3.8 啟動測試

      直接通過IDEA啟動tomcat就可以啦

      技巧01:應用啟動成功后,會自動訪問webapp里面的index.jsp頁面

 

4 添加框架支持

  我們創建的Web應用知識一個架子,不過IDEA支持自動添加框架;這樣就不需要手動在pom.xml中添加相關框架的依賴配置了

  右鍵項目 -> add framework stupport 

  技巧01:本博文主要添加spring框架的支持

  技巧02:點擊確認后會自動將spring框架的依賴包下載到項目中去【PS: 是直接將依賴下載到項目中的lib目錄下】,整個過程有點花時間

  跳坑01:如果下載依賴期間由於網絡原因失敗,這時候就需要重新添加框架;但是這時候發現已經沒有spring相關的選項了

  填坑01:這是后就需要進入到項目結構中的modules配置中,將spring相關的模塊刪除,在重新進行框架添加

  技巧03:添加完spring框架支持后會在webapp文件夾下自動生成相關的配置文件,並在webapp中的web.xml中對這些配置文件記性監聽配置

 

5 Bean相關

  Bean相關的詳細內容請參見《精通spring4.x企業應用開發實戰》

  5.1 配置bean

    5.1.1 准備

      在pom.xml文件中引入lombok依賴

      創建Student類和Teacher類

package domain;

import lombok.Data;

/**
 * @author 王楊帥
 * @create 2018-08-10 20:43
 * @desc 學生實體類
 **/
@Data
public class Student {

    private String id;
    private String name;
    private Integer age;
    private String address;

    public void info() {
        System.out.println("我是學生,我在學習控制反轉相關知識點。");
    }

}
Student.java
package domain;

/**
 * @author 王楊帥
 * @create 2018-08-10 20:45
 * @desc 老師實體類
 **/
public class Teacher {

    private String id;
    private String name;
    private Integer age;
    private String address;

    public void info() {
        System.out.println("我是老師,我在教授IOC相關知識點。");
    }

}
Teacher.java

    5.1.2 利用xml配置

      技巧01:需要將配置文件放到resources文件夾下【之前通過添加spring框架支持時產生的配置文件位於webapp下面,移動后需要更改web.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="student" class="domain.Student"></bean>

</beans>
View Code

    5.1.3 利用類注解配置

package core.config;

import domain.Teacher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 王楊帥
 * @create 2018-08-10 20:59
 * @desc bean配置類
 **/
@Configuration
public class Beans {

    @Bean(value = "teacher")
    public Teacher buildTeacher() {
        return new Teacher();
    }

}
Beans.java

  5.2 獲取bean

     5.2.1 利用BeanFactory獲取

    /**
     * 利用BeanFactory獲取bean
     * @throws IOException
     */
    @Test
    public void test01() throws IOException {
        System.out.println("Hello Boy");
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource resource = resolver.getResource("classpath:applicationContext.xml");

        System.out.println(resource.getURL());

        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(resource);

        System.out.println("初始化BeanFactory完畢");

        Student student = factory.getBean("student", Student.class);
        System.out.println("student bean 獲取成功");

        student.info();

    }
View Code

    5.2.2. 利用ApplicationContext獲取

      技巧01:利用ApplicationContext獲取xml配置的bean和配置類配置的bean需要用不同的實現類

    /**
     * 利用ApplicationContext獲取bean
     */
    @Test
    public void test02() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Student student = applicationContext.getBean("student", Student.class);

        student.info();
    }

    /**
     * 利用ApplicationContext獲取配置類配置的bean
     */
    @Test
    public void test03() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Beans.class);
        Teacher teacher = applicationContext.getBean("teacher", Teacher.class);

        teacher.info();

    }
View Code

    5.2.3 獲取bean代碼匯總

package domain;

import core.config.Beans;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;

/**
 * @author 王楊帥
 * @create 2018-08-10 20:47
 * @desc 測試類
 **/
public class TestDemo {

    @Before
    public void init() {
        System.out.println("初始化方法");
    }

    /**
     * 利用BeanFactory獲取bean
     * @throws IOException
     */
    @Test
    public void test01() throws IOException {
        System.out.println("Hello Boy");
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource resource = resolver.getResource("classpath:applicationContext.xml");

        System.out.println(resource.getURL());

        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(resource);

        System.out.println("初始化BeanFactory完畢");

        Student student = factory.getBean("student", Student.class);
        System.out.println("student bean 獲取成功");

        student.info();

    }

    /**
     * 利用ApplicationContext獲取bean
     */
    @Test
    public void test02() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Student student = applicationContext.getBean("student", Student.class);

        student.info();
    }

    /**
     * 利用ApplicationContext獲取配置類配置的bean
     */
    @Test
    public void test03() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Beans.class);
        Teacher teacher = applicationContext.getBean("teacher", Teacher.class);

        teacher.info();

    }

}
View Code

    

6 web.xml配置

  6.1 當前項目出現的問題

    由於我們在5.1.2的時候將bean相關的配置文件都移動到了resources目錄下,但是web.xml中還沒有做對應的修改;默認web.xml的配置文件是放在WEB-INF下面的,默認的web.xml配置文件信息如下

    我們將配置文件移動到resources目錄下后,在不更改web.xml配置文件的情況下啟動taomcat運行項目的報錯信息如下(報錯原因就是web.xml的配置中還是在WEB-INF下面去尋找配置文件,但是我們已經將配置文件移動到了resources目錄下,所以會報IO異常):

  6.2 修改web.xml中的配置文件路徑

    技巧01:如果在web.xml中不寫任何參數配置信息,默認的路徑是"/WEB-INF/applicationContext.xml,  在WEB-INF目錄下創建的xml文件的名稱必須是applicationContext.xml

    技巧02:可以同時配置多個配置文件路徑信息,它們之間用逗號隔開

  6.3 再次啟動的效果

    啟動結果:修改完web.xml中的配置文件路徑后,再次啟動容器時,雖然可以正常啟動,但是在啟動時會報一個錯誤,錯誤信息如下:

    報錯原因:使用springMVC時需要配置DispatcherServlet, DispatcherServlet 需要一個配置文件,該配置文件的默認值時WEB-INF下面的dispatcher-servlet.xml,我們已經將其移動到了resouces目錄下,所以會報錯。

    解決辦法:在配置DispatcherServlet 時利用 <init-param>  重新指定默認配置文件的位置【PS: 隨便指定一個即可,本案例指定的是一個空的配置文件dispatcher-servlet.xml】

  6.4 web.xml配置詳情

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

    <!-- 在Spring框架中是如何解決從頁面傳來的字符串的編碼問題的呢?
    下面我們來看看Spring框架給我們提供過濾器CharacterEncodingFilter  
     這個過濾器就是針對於每次瀏覽器請求進行過濾的,然后再其之上添加了父類沒有的功能即處理字符編碼。  
      其中encoding用來設置編碼格式,forceEncoding用來設置是否理會 request.getCharacterEncoding()方法,設置為true則強制覆蓋之前的編碼格式。-->  
    <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>  
        <init-param>  
            <param-name>forceEncoding</param-name>  
            <param-value>true</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>characterEncodingFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    <!-- 項目中使用Spring 時,applicationContext.xml配置文件中並沒有BeanFactory,要想在業務層中的class 文件中直接引用Spring容器管理的bean可通過以下方式-->  
    <!--1、在web.xml配置監聽器ContextLoaderListener-->  
    <!--ContextLoaderListener的作用就是啟動Web容器時,自動裝配ApplicationContext的配置信息。因為它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,啟動容器時,就會默認執行它實現的方法。  
    在ContextLoaderListener中關聯了ContextLoader這個類,所以整個加載配置過程由ContextLoader來完成。  
    它的API說明  
    第一段說明ContextLoader可以由 ContextLoaderListener和ContextLoaderServlet生成。  
    如果查看ContextLoaderServlet的API,可以看到它也關聯了ContextLoader這個類而且它實現了HttpServlet這個接口  
    第二段,ContextLoader創建的是 XmlWebApplicationContext這樣一個類,它實現的接口是WebApplicationContext->ConfigurableWebApplicationContext->ApplicationContext->  
    BeanFactory這樣一來spring中的所有bean都由這個類來創建  
     IUploaddatafileManager uploadmanager = (IUploaddatafileManager)    ContextLoaderListener.getCurrentWebApplicationContext().getBean("uploadManager");
     -->  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  
    <!--2、部署applicationContext的xml文件-->  
    <!--如果在web.xml中不寫任何參數配置信息,默認的路徑是"/WEB-INF/applicationContext.xml,  
    在WEB-INF目錄下創建的xml文件的名稱必須是applicationContext.xml。  
    如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個context參數:  
    在<param-value> </param-value>里指定相應的xml文件名,如果有多個xml文件,可以寫在一起並以“,”號分隔。  
    也可以這樣applicationContext-*.xml采用通配符,比如這那個目錄下有applicationContext-ibatis-base.xml,  
    applicationContext-action.xml,applicationContext-ibatis-dao.xml等文件,都會一同被載入。  
    在ContextLoaderListener中關聯了ContextLoader這個類,所以整個加載配置過程由ContextLoader來完成。-->  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:spring/applicationContext.xml</param-value>  
    </context-param>  

    <!--如果你的DispatcherServlet攔截"/",為了實現REST風格,攔截了所有的請求,那么同時對*.js,*.jpg等靜態文件的訪問也就被攔截了。-->  
    <!--方案一:激活Tomcat的defaultServlet來處理靜態文件-->  
    <!--要寫在DispatcherServlet的前面, 讓 defaultServlet先攔截請求,這樣請求就不會進入Spring了,我想性能是最好的吧。-->  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.css</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.swf</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.gif</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.jpg</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.png</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.js</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.html</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.xml</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.json</url-pattern>  
    </servlet-mapping>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>*.map</url-pattern>  
    </servlet-mapping>  
    <!--使用Spring MVC,配置DispatcherServlet是第一步。DispatcherServlet是一個Servlet,,所以可以配置多個DispatcherServlet-->  
    <!--DispatcherServlet是前置控制器,配置在web.xml文件中的。攔截匹配的請求,Servlet攔截匹配規則要自已定義,把攔截下來的請求,依據某某規則分發到目標Controller(我們寫的Action)來處理。-->  
    <servlet>  
        <servlet-name>DispatcherServlet</servlet-name><!--在DispatcherServlet的初始化過程中,框架會在web應用的 WEB-INF文件夾下尋找名為[servlet-name]-servlet.xml 的配置文件,生成文件中定義的bean。-->  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <!--指明了配置文件的文件名,不使用默認配置文件名,而使用dispatcher-servlet.xml配置文件。-->  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <!--其中<param-value>**.xml</param-value> 這里可以使用多種寫法-->  
            <!--1、不寫,使用默認值:/WEB-INF/<servlet-name>-servlet.xml-->  
            <!--2、<param-value>/WEB-INF/classes/dispatcher-servlet.xml</param-value>-->  
            <!--3、<param-value>classpath*:dispatcher-servlet.xml</param-value>-->  
            <!--4、多個值用逗號分隔-->  
            <param-value>classpath:spring/dispatcher-servlet.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup><!--是啟動順序,讓這個Servlet隨Servletp容器一起啟動。-->  
    </servlet>  
    <servlet-mapping>  
        <!--這個Servlet的名字是dispatcher,可以有多個DispatcherServlet,是通過名字來區分的。每一個DispatcherServlet有自己的WebApplicationContext上下文對象。同時保存的ServletContext中和Request對象中.-->  
        <!--ApplicationContext是Spring的核心,Context我們通常解釋為上下文環境,我想用“容器”來表述它更容易理解一些,ApplicationContext則是“應用的容器”了:P,Spring把Bean放在這個容器中,在需要的時候,用getBean方法取出-->  
        <servlet-name>DispatcherServlet</servlet-name>  
        <!--Servlet攔截匹配規則可以自已定義,當映射為@RequestMapping("/user/add")時,為例,攔截哪種URL合適?-->  
        <!--1、攔截*.do、*.htm, 例如:/user/add.do,這是最傳統的方式,最簡單也最實用。不會導致靜態文件(jpg,js,css)被攔截。-->  
        <!--2、攔截/,例如:/user/add,可以實現現在很流行的REST風格。很多互聯網類型的應用很喜歡這種風格的URL。弊端:會導致靜態文件(jpg,js,css)被攔截后不能正常顯示。 -->  
        <url-pattern>/</url-pattern> <!--會攔截URL中帶“/”的請求。-->  
    </servlet-mapping>  

    <welcome-file-list><!--指定歡迎頁面-->  
        <welcome-file>login.html</welcome-file>  
    </welcome-file-list>  
    <error-page> <!--當系統出現404錯誤,跳轉到頁面nopage.html-->  
        <error-code>404</error-code>  
        <location>/nopage.html</location>  
    </error-page>  
    <error-page> <!--當系統出現java.lang.NullPointerException,跳轉到頁面error.html-->  
        <exception-type>java.lang.NullPointerException</exception-type>  
        <location>/error.html</location>  
    </error-page>  
    <session-config><!--會話超時配置,單位分鍾-->  
        <session-timeout>360</session-timeout>  
    </session-config>  
</web-app>
View Code

    參考博文   

    

7 利用注解配置Bean

  利用XML或者java配置類來配置Bean都比較麻煩,從spring2.0開始就支持利用注解來配置Bean,常用的注解如下(詳情參見《精通Spring4.x企業應用開發實戰》P155):

    @Repository

    @Service

    @Controller

    @Component

  7.1 注解配置Bean實戰

    7.1.1 創建一個實例

      技巧01:在該注解上添加@Component注解

      技巧02:通過注解配置Bean時默認的Bean名稱是對應類的類名首字母小寫后的結果,當然也可以通過注解的value屬性進行指定

package domain;

import lombok.Data;
import org.springframework.stereotype.Component;

/**
 * @author 王楊帥
 * @create 2018-08-11 15:46
 * @desc
 **/
@Data
@Component
public class Dog {
    private String id;
    private String name;

    public void info() {
        System.out.println("我是哮天犬");
    }
}
Dog.java

    7.1.2 配置Bean配置注解掃描

      技巧01:在配置文件中添加掃描類包來應用注解定義的Bean

      技巧02:配置前掃描包前需要在配置文件中先進行命名空間的聲明(詳情參見《精通Spring4.x企業應用開發實戰》P117)

    7.1.3 測試一下

    @Test
    public void test01() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Dog dog = applicationContext.getBean("dog", Dog.class);
        dog.info();
    }
利用應用上下文獲取Bean

      跳坑01:直接利用@Autowired進行依賴注入配置好的Bean是總是失敗,錯誤信息如下

      填坑01:參考博文

 

8 自動裝配Bean

  傳統的注入方式有:構造器注入、set注入(屬性注入)、工廠方法注入(詳情參見《精通Spring4.x企業應用開發實戰》P121)

  實現依賴注入的注解有(詳情參見《精通Spring4.x企業應用開發實戰》P157):

    @Autowired -> 根據類型注入【推薦使用】

    @Resource -> 根據Bean名稱注入

    @Inject -> 根據類型注入

 

9 MVC配置

  前后端分離的項目,后台根據不同的URL調用不同的類及其方法進行邏輯操作,操作完畢后后台需要向前台返回JSON的數據。

  9.1 配置步驟

    9.1.1 修改web.xml中DispatcherServlet配置

      技巧01:DispacherServlet是用來攔截請求的,前后端分離項目中DispacherServlet會將攔截到的請求url分發到對應的類進行邏輯處理

      技巧02:默認的DispacherServlet配置只是攔截 .form 結尾的請求url,本案例修改為攔截請求url中帶 / 的所有請求

    9.1.2 利用注解編寫控制層

      技巧01:控制層就是處理DispatcherServlet攔截到的請求url的類【就是進行邏輯處理的入口】

      技巧02:lombok的日志使用logback實現的,所以需要導入logback依賴

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.16.20</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
lombok和logback依賴
package cn.xiangxu.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 王楊帥
 * @create 2018-08-11 16:22
 * @desc
 **/
@RestController
@RequestMapping(value = "/test")
@Slf4j
public class TestConroller {

    @GetMapping
    public String test01() {
        String result = "前后台連接測試";
        log.info(result);
        return result;
    }

}
TestConroller.java

    9.1.3 開啟MVC注解支持

 

10 本博文參考源代碼

  點擊下載源代碼

 

11 參考博文

  項目創建 

  添加框架依賴

    web.xml配置詳解

  springMVC配置詳解

 

 

 

      

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM