Restful项目环境搭建实例(Jpa+Jersey+Guice)

一、开发工具:Intellij IDEA,Gradle

二、项目技术:Jpa、Jersey、Guice、Jetty.   数据库:oracle

三、环境搭建步骤

1、在Intellj IDEA中新建gradle项目选择web创建,创建成功后会在项目根目录生成build.gradle文件。项目使用gradle管理jar依赖,gradle集合了Ant和Maven构建工具的优点。build.gradle文件中填写项目所需要的jar依赖,内容如下:

group 'yu_practice_project'
version '1.0-SNAPSHOT'
//二进制插件
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'war'

//指定jdk版本
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile group: 'org.hibernate', name: 'hibernate-core', version: '4.3.11.Final'
    compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '4.3.9.Final'
    compile group: 'org.hibernate', name: 'hibernate-c3p0', version: '4.3.11.Final'
    compile group: 'com.google.inject', name: 'guice', version: '3.0'
    compile group: 'com.google.guava', name: 'guava', version: '20.0'
    compile group: 'com.google.inject', name: 'guice', version: '4.1.0'
    compile group: 'com.google.inject.extensions', name: 'guice-persist', version: '4.1.0'
    compile group: 'com.google.inject.extensions', name: 'guice-servlet', version: '4.1.0'
    compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
    compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.4.6.v20170531'
    compile group: 'org.eclipse.jetty', name: 'jetty-webapp', version: '9.4.6.v20170531'
    compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.22.2'
    compile group: 'com.sun.jersey', name: 'jersey-servlet', version: '1.19.4'
    compile group: 'com.sun.jersey.contribs', name: 'jersey-guice', version: '1.19.4'
    testCompile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.25'
    compile fileTree(dir:'libs',include:['*.jar'])
}
其中,fileTree中包含的外部的jar是oracle数据库的jdbc驱动(因为maven中央仓库没有这个驱动),libs文件夹放在系统的根目录。

最后项目的目录结构如下:


注:其中的一些目录是需要自己手工创建的,如resoures和下面的META-INF等,persisitence.xml文件必须放在META-INF文件夹下

2、首先创建jpa的persistence.xml配置文件,和数据库连接的properties文件。数据库连接的属性也可以在persistence.xml文件中配置,此处不做说明。sql_dsl是创建表文件,需要手工在oracle数据库中执行。practice-log4j.log是log4j的日志文件。

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
     http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="domain" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <class>com.first.domain.Message</class>
    </persistence-unit>
</persistence>

hibernate.properties

hibernate.connection.driver_class = oracle.jdbc.driver.OracleDriver
hibernate.connection.url = jdbc:oracle:thin:@localhost:1521:orcl
hibernate.connection.username = admin
hibernate.connection.password = admin
hibernate.dialect = org.hibernate.dialect.OracleDialect
hibernate.show_sql = true
hibernate.format_sql = true

hibernate.c3p0.min_size = 5
hibernate.c3p0.max_size = 30
hibernate.c3p0.time_out = 1800
hibernate.c3p0.max_statement = 50

log4j.properties

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=practice-log4j.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

# Root logger option
log4j.rootLogger=INFO, file, stdout

# Log everything. Good for troubleshooting
log4j.logger.org.hibernate=INFO

# Log all JDBC parameters
log4j.logger.org.hibernate.type=ALL

sql_dsl.sql

create TABLE message_practice (
	m_id VARCHAR2(12) not null,
	message_name VARCHAR2(50) ,
	message_note VARCHAR2(100)
);
comment on table message_practice is '信息表';
comment on COLUMN message_practice.m_id is 'ID';
comment on COLUMN message_practice.message_name is '信息名称';
comment on COLUMN message_practice.message_note is '信息内容';
alter table message_practice add constraint PK_M_ID primary key (m_id);
2、创建实体类 Message.java,实体类需要在 persistence.xml中填写对应的映射

package com.first.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name = "MESSAGE_PRACTICE")
@XmlRootElement
public class Message {
    @Id
    @Column(name = "M_ID")
    private String mId;

    @Column(name = "MESSAGE_NAME")
    private String messageName;

    @Column(name = "MESSAGE_NOTE")
    private String messageNote;

    public Message() {
    }

    public Message(String mId, String messageName, String messageNote) {
        this.mId = mId;
        this.messageName = messageName;
        this.messageNote = messageNote;
    }
    此处省略setter、getter方法.....
}

创建数据库操作类BaseFacade.java

package com.first.guice.jpa;

import com.first.domain.Message;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;

import javax.persistence.EntityManager;
import java.util.List;

public class BaseFacade {

    @Inject
    private EntityManager entityManager;

    public Message find(String id){
        Message message = entityManager.find(Message.class,id);
        return message;
    }
    
    public List<Message> findAll(){
        List<Message> messageList = entityManager.createQuery("from Message").getResultList();
        return messageList;
    }

    @Transactional
    public void saveMessage(Message message){
        entityManager.persist(message);
    }
}

创建业务类 GetPractice.java

package com.first.Jersey;

import com.first.domain.Message;
import com.first.guice.jpa.BaseFacade;
import com.google.inject.Inject;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/api/get-practice")
public class GetPractice {

    @Inject
    private BaseFacade baseFacade;

    @GET
    @Path("get-message")
    @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
    public List<Message> getMessage(){
        return baseFacade.findAll();
    }
}
3、创建Guice module模块,绑定实例和指定jersey的包位置

创建JerseyModule.java

package com.first.guice.module;

import com.first.Jersey.GetPractice;
import com.first.guice.jpa.BaseFacade;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;

import java.util.HashMap;
import java.util.Map;

import static com.sun.jersey.api.core.PackagesResourceConfig.PROPERTY_PACKAGES;

public class JerseyModule extends JerseyServletModule {
    @Override
    protected void configureServlets() {

        bind(BaseFacade.class);
        bind(GetPractice.class);
        bind(GuiceContainer.class);

        Map<String, String> params = new HashMap<>();
        params.put(PROPERTY_PACKAGES, "com.first.Jersey");
        //这里控制jersey注解path的过滤,和指定jersey api所在的包(可以在web.xml中配置)
        serve("/*").with(GuiceContainer.class, params);
    }
}
4、创建一个servlet监听类,用来创建Guice的Injector实例,启动jpa和装载JerseyModule模块,并设置PersistFilter,这个持久化过滤器在web应用中是必须的

创建GuiceServletService.java

package com.first.guice.ServletExtention;

import com.first.guice.module.JerseyModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.persist.PersistFilter;
import com.google.inject.persist.jpa.JpaPersistModule;
import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletModule;

public class GuiceServletService extends GuiceServletContextListener{
    @Override
    protected Injector getInjector() {
        System.out.println("guiceServletService");
        return Guice.createInjector(new ServletModule(){
            @Override
            protected void configureServlets() {
		//此处的domain是persistence.xml中定义的name
                install(new JpaPersistModule("domain"));
                install(new JerseyModule());
                //持久化过滤器,web程序必须的,代替了PersistService的start()初始化启动
                filter("/*").through(PersistFilter.class);
            }
        });
    }
}
5、最后是配置 web.xml文件,需要添加监听和GuiceFilter

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>yu_practice_first</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
   <!--这是guice的servelt过滤支持-->
    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/api/*</url-pattern>
    </filter-mapping>
    <!--此处配置可以在module类中加载-->
    <!--<servlet>-->
        <!--<servlet-name>Jersey REST Service</servlet-name>-->
        <!--<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>-->
        <!--<init-param>-->
            <!--<param-name>com.sun.jersey.config.property.packages</param-name>-->
            <!--<param-value>com.first.Jersey</param-value>-->
        <!--</init-param>-->
        <!--<load-on-startup>1</load-on-startup>-->
    <!--</servlet>-->
    <!--<servlet-mapping>-->
        <!--<servlet-name>Jersey REST Service</servlet-name>-->
        <!--<url-pattern>/*</url-pattern>-->
    <!--</servlet-mapping>-->
    <listener>
        <listener-class>com.first.guice.ServletExtention.GuiceServletService</listener-class>
    </listener>
</web-app>
6、创建启动jetty服务器的main类

JettyServer.java

package com.first.mainTest;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;

public class JettyServer {
    private static final String DEFAULT_CONTEXT_PATH = "/yu_practice_first";
    private static final String DEFAULT_APP_CONTEXT_PATH = "src/main/webApp";
    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        WebAppContext webAppContext = new WebAppContext(DEFAULT_APP_CONTEXT_PATH,DEFAULT_CONTEXT_PATH);
        webAppContext.setDescriptor(DEFAULT_APP_CONTEXT_PATH + "/WEB-INF/web.xml");
        webAppContext.setResourceBase(DEFAULT_APP_CONTEXT_PATH);
        webAppContext.setParentLoaderPriority(true);
        server.setHandler(webAppContext);
        server.start();
        server.join();
    }
}

如控制台未出现错误,则启动成功,在浏览器中输入地址: http://localhost:8080/yu_practice_first/api/get-practice/get-message,如果出现以下页面则项目搭建成功:

注:这里查出的数据是之前预先存在数据库中,你可以使用BaseFacade.java中的方法添加数据。






评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值