Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 59

6
votes
answers
25 views
+10

JSF 2.0: use Enum values for selectOneMenu [duplicate]

This question already has an answer here:

I'm using JSF 2.0 and want to fill a selectOneMenu with the values of my Enum. A simple example:

// Sample Enum
public enum Gender {
  MALE("Male"),
  FEMALE("Female");

  private final String label;

  private Gender(String label) {
    this.label = label;
  }

  public String getLabel() {
    return this.label;
  }
}

Unfortunately, i can't use Seam for my current project, which had a nice <s:convertEnum/> Tag that did most of the work. In Seam, to use the values of the Enum, i had to write the following markup (and create a factory that provides the #{genderValues}:

<!-- the Seam way -->
<h:selectOneMenu id="persongender" value="#{person.gender}">
  <s:selectItems var="_gender" value="#{genderValues}"" label="#{_gender.label}"/>
  <s:convertEnum/>
</h:selectOneMenu>

The result is that i don't have to declare the Enum values explicitely anymore inside the markup. I know that this is not very easy in JSF <2.0, but is there any new in JSF2 to help with this issue? Or does Weld help here somehow? If there is nothing new in JSF2, what's the easiest way to do it in JSF 1.2?

Or can i even integrate the Seam JSF tag and the corresponding classes of Seam to get the same feature in a JavaEE6-App (without the Seam container)?

沙发
+40

我前段時間遇到過這個問題並且我像你一樣解決了這個問題,但後來我意識到我用這個解決方案我不能使用i18n,因為字符串在枚舉類中是硬編碼的。所以我修改了我的enumConverter以使用 messages 進行渲染。

有時您可能希望將枚舉呈現為一些唯一標識符而不是用戶可讀文本(用於某些內部用法)組件)。

這是我的轉換器:

  import java.util.ResourceBundle; / * *根據一個或多個貢獻者許可協議許可給Apache Software Foundation(ASF)。有關版權所有權的其他信息,請參閱隨此工作分發的NOTICE文件*。ASF根據Apache許可證向您授予此文件*,版本2.0(*“許可證”); 您不得使用此文件,除非符合許可證*。您可以通過* * http://www.apache.org/licenses/LICENSE-2.0獲取許可證副本* *除非適用法律要求或書面同意,*根據許可證分發的軟件在*上分發“原樣”基礎,不含任何*明示或暗示的保證或條件。有關管理許可下的權限和限制*的*特定語言,請參閱許可證。* / import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException; import com.eyeprevent.configuration.ConfigurationReader; / ** *以使轉換可逆的方式轉換枚舉(有時)*&lt; ul&gt; *&lt; li&gt; input:使用其classname和ordinal,reversible&lt; li&gt; *&lt; li&gt; else:使用其名稱,不可逆&lt; li&gt; *&lt; / ul&gt; * / public class EnumConverter實現Converter {@SuppressWarnings(“unchecked”)public Object getAsObject(FacesContext context,UIComponent component,String value)throws ConverterException {if(value == null || value.length()&lt; 1){return空值; } int pos = value.indexOf('@'); if(pos&lt; 0){throw new IllegalArgumentException(value +“not point to enum”); } String className = value.substring(0,pos); 類clazz; int ordinal = Integer.parseInt(value.substring(pos + 1),10); try {clazz = Class.forName(className,true,Thread.currentThread()。getContextClassLoader()); //如果clazz不是枚舉,它可能是繼承的枚舉。在這種情況下,嘗試找到超類。while(clazz!= null&amp;&amp;!clazz.isEnum()){clazz = clazz.getSuperclass(); } if(clazz == null){throw new IllegalArgumentException(“class”+ className +“不能被視為enum”); } Enum [] enums =(Enum [])clazz.getEnumConstants(); if(enums.length&gt; = ordinal){return enums [ordinal]; catch(ClassNotFoundException e1){throw new RuntimeException(e1); 拋出新的IllegalArgumentException(“ordinal”+ ordinal +“在enum中找不到”+ clazz); public String getAsString(FacesContext context,UIComponent component,Object value)throws ConverterException {if(value == null){return“”; } Enum&lt;?&gt; e =(Enum&lt;?&gt;)值; if(組件實例UIInput || UIInput.COMPONENT_FAMILY.equals(component.getFamily())){return e.getClass()。getName()+“@”+ Integer.toString(e.ordinal(),10); } ResourceBundle messages = ConfigurationReader.getMessages(context.getViewRoot()。getLocale()); return messages.getString(e.name()); }}  
     
			
        
板凳
+20

我使用這種簡單的方法,非常樂觀,您可以根據自己的需要進行自定義。我將以下代碼放在可重用的bean中,可以隨時從您的應用程序中調用,因此您可以使用在包中聲明的任何枚舉。

  public List&lt; String&gt; fromEnum(String cname){List&lt; String&gt; names = new ArrayList&lt;&gt;(); 嘗試{Class c = Class.forName(cname); Object [] r = c.getEnumConstants(); if(r!= null){for(Object o:r){names.add(o.toString()); catch(ClassNotFoundException ex){FaceUtil.ShowError(ex); 返回名稱; public static void ShowError(Exception ex){FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR,ex.getMessage(),“Error Message”); FacesContext.getCurrentInstance()。addMessage(null,msg); }   

現在在xhtml文件中使用它,如下所示:

 &lt; p:selectOneMenu value =“#{jobapp.aplicant.marital}”&gt ; &lt; f:selectItems value =“#{rtutil.fromEnum('com.company.package.enMarital')}”var =“m”itemLabel =“#{m}”itemValue =“#{m}”/&gt; &LT; / P:selectOneMenu用於&GT;    

現在在xhtml文件中使用它,如下所示:

 &lt; p:selectOneMenu value =“#{jobapp.aplicant.marital}”&gt; &lt; f:selectItems value =“#{rtutil.fromEnum('com.company.package.enMarital')}”var =“m”itemLabel =“#{m}”itemValue =“#{m}”/&gt; &LT; / P:selectOneMenu用於&GT;    

現在在xhtml文件中使用它,如下所示:

 &lt; p:selectOneMenu value =“#{jobapp.aplicant.marital}”&gt; &lt; f:selectItems value =“#{rtutil.fromEnum('com.company.package.enMarital')}”var =“m”itemLabel =“#{m}”itemValue =“#{m}”/&gt; &LT; / P:selectOneMenu用於&GT;  
     
			
        
0
votes
answers
49 views
+10

persistence.xml文件是不是在classpath

-1

所以我試圖建立使用Wildfly,JPA,Hibernate和MariaDB的使用Maven在Eclipse的adminsystem。我在WildFly管理控制檯中配置了我的數據源,一切正常。 Succesful connection picture in WildFly 現在我試圖寫入該項目與實體管理器工廠的數據庫在Eclipse。但我有此錯誤消息: Error message in Eclipse 在這裏你可以看到我的項目樹: Project treepersistence.xml文件是不是在classpath

這裏是我的POM:

<?xml version="1.0" encoding="UTF-8"?> 
<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.gyurmatag.adminsystem</groupId> 
<artifactId>adminsystem</artifactId> 
<version>1.0</version> 
<packaging>war</packaging> 

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <java.version>1.8</java.version> 

    <servlet.version>3.1.0</servlet.version> 
    <jsf.version>2.2.12</jsf.version> 
    <primefaces.version>5.3</primefaces.version> 

    <version.wildfly>9.0.2.Final</version.wildfly> 
    <jboss.home>${project.build.directory}/wildfly-${version.wildfly} 
    </jboss.home> 
    <server.config>standalone.xml</server.config> 

    <maven-compiler-plugin.version>3.3</maven-compiler-plugin.version> 
    <maven-dependency-plugin>2.10</maven-dependency-plugin> 
    <maven-resources-plugin.version>2.7</maven-resources-plugin.version> 
    <wildfly-maven-plugin.version>1.1.0.Alpha5</wildfly-maven-plugin.version> 
</properties> 

<dependencies> 
    <!-- Servlet --> 
    <dependency> 
     <groupId>javax.servlet</groupId> 
     <artifactId>javax.servlet-api</artifactId> 
     <version>${servlet.version}</version> 
     <scope>provided</scope> 
    </dependency> 
    <!-- JSF --> 
    <dependency> 
     <groupId>com.sun.faces</groupId> 
     <artifactId>jsf-api</artifactId> 
     <version>${jsf.version}</version> 
     <scope>compile</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.sun.faces</groupId> 
     <artifactId>jsf-impl</artifactId> 
     <version>${jsf.version}</version> 
     <scope>compile</scope> 
    </dependency> 
    <!-- PrimeFaces --> 
    <dependency> 
     <groupId>org.primefaces</groupId> 
     <artifactId>primefaces</artifactId> 
     <version>${primefaces.version}</version> 
    </dependency>  

    <!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java- 
client --> 
    <dependency> 
     <groupId>org.mariadb.jdbc</groupId> 
     <artifactId>mariadb-java-client</artifactId> 
     <version>2.2.0</version> 
    </dependency> 

    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-core</artifactId> 
     <version>5.2.12.Final</version> 
    </dependency> 

    <dependency> 
     <groupId>org.hibernate.javax.persistence</groupId> 
     <artifactId>hibernate-jpa-2.1-api</artifactId> 
     <version>1.0.0.Final</version> 
    </dependency> 


    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate- 
entitymanager --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>5.2.12.Final</version> 
    </dependency> 

</dependencies> 

<build> 
<pluginManagement> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <version>${maven-compiler-plugin.version}</version> 
      <configuration> 
       <source>${java.version}</source> 
       <target>${java.version}</target> 
      </configuration> 
     </plugin> 
     <!-- Unpack the distribution --> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-dependency-plugin</artifactId> 
      <version>${maven-resources-plugin.version}</version> 
      <executions> 
       <execution> 
        <id>unpack-wildfly</id> 
        <phase>generate-sources</phase> 
        <goals> 
         <goal>unpack</goal> 
        </goals> 
        <configuration> 
         <artifactItems> 
          <artifactItem> 
           <groupId>org.wildfly</groupId> 
           <artifactId>wildfly-dist</artifactId> 
           <version>${version.wildfly}</version> 
           <type>zip</type> 
           <overWrite>false</overWrite> 
           <outputDirectory>${project.build.directory} 
</outputDirectory> 
          </artifactItem> 
         </artifactItems> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 
     <!-- Copy server configuration --> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-resources-plugin</artifactId> 
      <version>${maven-resources-plugin.version}</version> 
      <executions> 
       <execution> 
        <id>copy-standalone-xml</id> 
        <phase>generate-sources</phase> 
        <goals> 
         <goal>copy-resources</goal> 
        </goals> 
        <configuration> 

<outputDirectory>${jboss.home}/standalone/configuration</outputDirectory> 
         <resources> 
          <resource> 
           <directory>src/main/resources</directory> 
          </resource> 
         </resources> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 
     <!-- Maven WildFly plugin --> 
     <plugin> 
      <groupId>org.wildfly.plugins</groupId> 
      <artifactId>wildfly-maven-plugin</artifactId> 
      <version>${wildfly-maven-plugin.version}</version> 
      <configuration> 
       <jbossHome>${jboss.home}</jbossHome> 
       <serverConfig>${server.config}</serverConfig> 
      </configuration> 
     </plugin> 
    </plugins> 
    </pluginManagement> 
</build> 

這裏是我的持久性。 XML:

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

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

       <jta-data-source>jboss/MariaDBDS</jta-data-source> 


       <properties> 
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /> 
        <property name="hibernate.hbm2ddl.auto" value="validate" /> 
        <property name="hibernate.show_sql" value="true" /> 
        <property name="hibernate.format_sql" value="true" /> 
        <property name="hibernate.connection.release_mode" value="auto" /> 
       </properties> 
      </persistence-unit> 

這裏是我JPAUtility類:

package com.gyurmatag.adminsystem.model; 


import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 


public class JPAUtility { 
private static final EntityManagerFactory emFactory; 
static { 
     emFactory = Persistence.createEntityManagerFactory("adminsystem"); 
} 
public static EntityManager getEntityManager(){ 
    return emFactory.createEntityManager(); 
} 
public static void close(){ 
    emFactory.close(); 
} 
} 

如果你想採取一個更仔細看看我的項目,你可以在這裏找到:Bitbucket repo

你能幫助我有了這個?

非常感謝! :)

+5

'persistence.xml'就是它應該被稱爲... – DN1

+0

這似乎是一個在問題中錯字... –

+0

是的。這是一個錯字。感謝您的答案! –

沙发
0
0

我懷疑你有太常見了「太多的依賴錯誤」。

更換所有你的依賴與:

<dependencies> 
    <dependency> 
     <groupId>javax</groupId> 
     <artifactId>javaee-api</artifactId> 
     <version>7.0</version> 
     <scope>provided</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.primefaces</groupId> 
     <artifactId>primefaces</artifactId> 
     <version>${primefaces.version}</version> 
    </dependency>  
</dependencies> 

,看你怎麼去...

+0

我的代碼中存在拼寫錯誤。無論如何感謝您的答案! –

+0

您應該解決您的依賴反正 –

+1

它工作正常... –

596
votes
answers
20 views
+10

web.xml is missing and is set to true

Consider:

Enter image description here

When I create a simple Maven project in Eclipse I am getting this error:

web.xml is missing and <failOnMissingWebXml> is set to true

How can I fix this problem?

up vote 151 down vote accepted favorite
沙发
+1510
+50

您也可以這樣做:

  1. 右鍵單擊項目瀏覽器中的部署描述符
  2. 選擇生成部署描述符存根

    它將在 src / main / webapp中生成 WEB-INF 文件夾以及 web.xml

我不建議在代碼中添加樣板,因為你的構建工具會出錯。 - Martijn Burger 2015年11月12日20:34

@MartijnBurger你能否告訴我們上述黑客可能產生的影響,如果可能的話還可以添加其他一些替代方案? - 會幫助像我這樣的新手程序員。謝謝。 - Sendhilkumar Alalasundaram 2016年3月14日13:27

請參閱下面的答案以獲取替代方案。上面的解決方案沒有錯,只是你應該盡力使你的最終產品盡可能乾淨。使用上面的解決方案,您的最終產品將最終得到一個不必要的web.xml文件。您應該在構建工具(即maven)中修復此問題。 - Martijn Burger 2016年3月17日12:31

您也可以參考:eggsylife.co.uk/2009/12/20/ - Satyendra 2016年4月25日15:14

這將在您的項目中添加不必要的文件,其他的事情是web.xml approcah已經過時了。如果你想刪除這個錯誤然後只是強制更新maven錯誤將消失 - jitendra varshney 1月29日7:48

+3590

這是一個maven錯誤。它表示它期望項目中的web.xml文件,因為它是一個Web應用程序,如&lt; packaging&gt; war&lt; / packaging&gt; 所示。但是,對於最近的Web應用程序,web.xml文件是完全可選的。Maven需要趕上這個慣例。將此添加到您的maven pom.xml 以讓maven趕上來,您不需要在項目中添加無用的 web.xml

 <代碼>&LT;建立&GT; &LT;插件&GT; &LT;插件&GT; &LT;&的groupId GT; org.apache.maven.plugins&LT; /&的groupId GT; &LT; artifactId的&GT;行家-戰爭插件&LT; / artifactId的&GT; &LT;版本&GT; 2.6&LT; /版本&GT; &LT;結構&gt; &LT; failOnMissingWebXml&GT假LT; / failOnMissingWebXml&GT; &LT; /結構&gt; &LT; /插件&GT; &LT; /插件&GT; &LT; /構建&GT;   

這是一個比添加空 web.xml 更好的解決方案,因為這樣您的最終產品保持乾淨,您只需更改構建參數。

對於更多當前版本的maven,您也可以使用較短版本:

 &lt; properties&gt; &LT; failOnMissingWebXml&GT假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;   假LT; / failOnMissingWebXml&GT; &LT; /結構&gt; &LT; /插件&GT; &LT; /插件&GT; &LT; /構建&GT;   

這是一個比添加空 web.xml 更好的解決方案,因為這樣您的最終產品保持乾淨,您只需更改構建參數。

對於更多當前版本的maven,您也可以使用較短版本:

 &lt; properties&gt; &LT; failOnMissingWebXml&GT假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;   假LT; / failOnMissingWebXml&GT; &LT; /結構&gt; &LT; /插件&GT; &LT; /插件&GT; &LT; /構建&GT;   

這是一個比添加空 web.xml 更好的解決方案,因為這樣您的最終產品保持乾淨,您只需更改構建參數。

對於更多當前版本的maven,您也可以使用較短版本:

 &lt; properties&gt; &LT; failOnMissingWebXml&GT假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;   

這是一個比添加空 web.xml 更好的解決方案,因為這樣您的最終產品保持乾淨,您只需更改構建參數。

更多當前版本maven你也可以使用較短的版本:

 &lt; properties&gt; &LT; failOnMissingWebXml&GT假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;   

這是一個比添加空 web.xml 更好的解決方案,因為這樣您的最終產品保持乾淨,您只需更改構建參數。

更多當前版本maven你也可以使用較短的版本:

 &lt; properties&gt; &LT; failOnMissingWebXml&GT假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;   假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;   假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;  
     
			
        

這個答案比其他答案更合理。 - smwikipedia 2015年11月23日6:52

這個答案必須標記為正確 - alexanoid 2015年12月5日11:01

如果您在Servlet 3.0+環境中使用並且具有Interface WebApplicationInitializer的任何實現,則此答案是正確的方法。這是解決這個問題的明智方法 - 在沒有它的情況下採取措施後添加web.xml毫無意義! - Geeb 2016年1月29日13:27

我將標記為解決方案...... - Gabriel Simas於2016年2月13日3:17

如下所示,請考慮更新您的答案以獲得更短的配置。包括 false 足以代替更詳細的插件配置設置。 - Olivier Cailloux於2016年8月10日21:49

+260

如果您已經在/ src / main / webapp / WEB-INF下安裝了web.xml但仍然出現錯誤“web.xml缺失且設置為true”,則可以檢查是否包含 /項目源中的src / main / webapp

以下是您可以遵循的步驟:

  1. 您可以通過右鍵單擊項目來檢查此項,然後打開其“屬性”對話框,然後打開“部署程序集”,在此處可以添加Folder / src / main / webapp。保存設置,然後,
  2. 轉到Eclipse菜單項目 - &gt; 清理......並清理項目,錯誤應該消失。

    (我用Eclipse Mars證實了這一點)

在“Eclipse Mars”下體驗過相同的問題,您所描述的解決方案非常完美!謝謝 - Hartmut P. 2015年12月23日16:10

沒有為我工作...我已經有這些文件夾,我甚至嘗試設置web.xml缺少false。它沒有工作.... - Baradwaj Aryasomayajula 2016年3月18日在5:37

+160

我有同樣的問題。經過學習和谷歌搜索,我已經解決了我的問題:

右鍵單擊項目文件夾,轉到 Java EE Tools ,選擇 Generate Deployment Descriptor Stub 這將在 src / main / webapp / WEB-INF 文件夾中創建 web.xml

我不建議在代碼中添加樣板,因為你的構建工具會出錯。 - Martijn Burger 2015年11月12日20:35

這與接受的答案是一樣的建議。 - 肯斯特於17年1月1日16:14

+150

你也可以這樣做,不那麼冗長

 &lt; properties&gt; &LT; failOnMissingWebXml&GT假LT; / failOnMissingWebXml&GT; &LT; /性狀&gt;  
     
			
        

最優雅的解決方案恕我直言。請參閱doc(和一個舊的eclipse錯誤,它阻止了這個解決方案的工作,現在已經解決了)。 - Olivier Cailloux於2016年8月10日21:51

+150

如果您使用Spring Tool Suite,Generate Deployment Descriptor Stub的選項會在Java EE Tools下移動,因此您:

  1. 右鍵單擊 項目
  2. 選擇 Java EE工具
  3. 選擇生成部署描述符存根選項

    這將在src / main / webapp / WEB-INF /文件夾中創建web.xml文件,當然也可以從Maven的pom.xml文件中刪除錯誤。

    < / p>

+70

Eclipse識別出錯誤的默認 webapp 目錄。因此,我們應該通過 maven-war-plugin 清楚地設置它。

 &lt; build&gt; &LT;插件&GT; &LT;插件&GT; &LT;&的groupId GT; org.apache.maven.plugins&LT; /&的groupId GT; &LT; artifactId的&GT;行家-戰爭插件&LT; / artifactId的&GT; &LT;版本&GT; 3.0.0&LT; /版本&GT; &LT;結構&gt; &LT; webappDirectory&GT; SRC /主/ web應用&LT; / webappDirectory&GT; &LT; /結構&gt; &LT; /插件&GT; &LT; /插件&GT; &LT; /構建&GT;   

保存此設置後,如果刪除它,錯誤將永遠不會出現。(我無法解釋原因。

+30

我遇到了同樣的問題,即使我的'src / main / webapp / WEB-INF /'文件夾中包含正確的 web.xml

Maven build重新創建(maven-&gt; eclipse)配置後問題消失了。我執行了 mvn eclipse:clean eclipse:eclipse <然後我用 Maven - &gt; 更新項目以添加(eclipse-&gt; maven)插件特定選項。

同樣在這裡,雖然我使用git reset --hard HEAD - Markus Barthlen 2016年9月9日13:52

謝謝,這對我也很有幫助。右鍵單擊 - > Maven - >更新項目 - trebor 16年11月9日23:38

你想要軟包裝還是硬包裝? - Ciro Santilli新疆改造中心996ICU六四事件2015年1月16日10:09

+20

我只在eclipse中遇到過這個問題,在Maven命令行中一切正常,我的web.xml文件已存在。這是一個受到影響的成熟項目(已在生產中部署)。我的問題與eclipse元數據有關。我的.settings /文件夾中的一個文件存在問題,特別是org.eclipse.wst.common.component已被更改。我能夠將此文件恢復到其先前版本,這解決了我的問題。

請注意,當我嘗試在eclipse屬性中單擊Deployment Assembly時,Yuci的答案對我不起作用,我收到一條錯誤消息,指出“當前顯示的頁麵包含無效值。”

我有相同的情況,不得不從我的.settings /文件夾恢復org.eclipse.wst.common.component文件,我的項目現在工作,顯然組件的內容被刪除,所以它沒有我的網絡的路徑。 xml文件。此外,當我試圖在eclipse屬性中打開Deployment Assembly時出現了同樣的錯誤:“當前顯示的頁麵包含無效值。” 我發現這個答案有點晚了,但這就是我解決它的方法。很棒的答案順便說一句。 - JorgeValdés於18年8月28日12:06

+10

執行此操作:

轉到並右鍵單擊Deployment Descriptor,然後單擊Generate Deployment Descriptor Stub。

+10

對於存在web.xml的項目項目 - &gt;屬性 - &gt;部署程序集,您可以在其中添加文件夾src / main / webapp。保存更改。清理項目以繼續。

對於沒有web.xml的項目在屬性標記下的pom.xml中將failOnMissingWebXml設置為false。

假設您當前的編輯器支持自動換行,它將自動換行。例如,pydev目前沒有(大約2014年1月)。 - ecoe 2014年1月14日0:04

Ctrl + Shift + F不會在火星上為我包裹長評論。 - PeterV.Mørch2015年9月23日21:06

對我不起作用。沒啥事兒。 - hepcat72 2015年10月23日20:58

它的工作令人驚訝! - 康斯坦丁於2016年5月15日16:58

呃..硬包裝。PS:關於“任何花哨的東西”,我從問題的“需要輸入文本段落”推斷出他不想在每一行的末尾按Enter鍵。所以我得出結論他正在尋找軟包裝。另外,他問是否有插件。 - ADTC於2016年5月26日10:28

0

只要沒有必要,創建一個只需要它的web.xml是沒有意義的。如果你有嵌入式servlet conatiner或沒有像spring-boot那樣的xml cfg,那就是這種情況。您只是在項目級別或全局的eclipse中禁用JavaEE(無用的東西)

  Eclipse / STS&gt; Windows&gt; Preferences&gt; JavaEE&gt; Doclet&gt; Webdoclet&gt; “取消選中”DeploymentDescriptor&gt; 好的 
     
			
        

完善。正是我在尋找什麼。 - Andreas_D 12年6月17日10:19

我已經安裝了你的Word Wrap插件,重新啟動了eclipse,但無法弄清楚Word Wrap的選項。我錯過了什麼嗎?我正在使用Eclipse Juno,並在Juno上安裝了PHP PDT。切換到兩個透視PHP / Jave EE,但即使在安裝Word Wrap插件後也似乎無法自動換行。你能幫我嗎?先感謝您。 - Sanjay Khadka 2013年4月22日2:06

可能它不適用於Juno版本。 - Sanjay Khadka 2013年4月22日2:10

安裝完成後,右鍵單擊編輯器中的任意位置並選擇“切換自動換行”,或按Ctrl-Alt-E。 - gbmhunter 13年12月10日2:46

0

選擇您的項目並選擇“Deployment Descriptor”選項,然後選擇“Generate Deployment Descriptor stub”

最後!+1。我已經在上面引用了你的答案。 - VonC於2016年2月22日9:43

我無法在Mac中啟用此功能。備用鍵盤快捷鍵(選項或命令)未激活它,它在“幫助”或任何其他菜單中不可用。 - Deborah 2016年12月8日0:11

在我的安裝中(Mac上為4.6.2),這是alt + cmd + Y - Christian 2017年3月14日16:55

如何激活此比較視圖? - dma_k 17年10月9日9:20

0

步驟:選擇您的項目並選擇“部署描述符”選項,然後選擇“生成部署描述符存根”工作正常。問題是我們並不總是需要web.xml,因此最好將false附加到pom.xml

-10

在src / webapp中創建WEB-INF文件夾,並在WEB-INF文件夾中包含web.xml頁面,然後

您使用哪個Android版本? - HefferWolf 2011年10月26日7:29

Min SDK版本7 - Android 2.1 - Mark Cameron 2011年10月26日7:31

我嘗試將目標更改為13,但它無法正常工作......可能是什麼原因? - Anirudh 12年11月11日3:53

@anirudhmaddy你使用“android:configChanges =”keyboard | keyboardHidden | orientation | screenLayout | uiMode | screenSize | smallestScreenSize“還是更短的?如果你將你的目標更改為13並使用更長的configChanges,它應該可以工作。 - GürcanKavakçıJan 13 '13 at 1:50

@ gurcan15是的,它現在正在工作。 - Anirudh 2013年1月15日4:24

-10

-web / .setting&amp; -admin / .setting

找不到了嗎?你用過哪個編輯器? - RainSia 2013年1月27日15:32

@africanherbsman也找不到“自動換行”選項。它是以特殊的視角還是以任何一種視角來指定的?我是C ++的人。 - 王2013年2月15日16:18

我在使用Default Eclipse Juno Java EE版本,但無法找到WOrd Wrap的選項。 - Sanjay Khadka 2013年4月22日2:09

-10

右鍵單擊該項目,轉到 Maven - &gt; 更新項目... ,然後檢查強制更新快照/版本,然後單擊確定它完成了!

0
votes
answers
24 views
+10

How to connect with Java into Active Directory

I am using Weblogic, Ejb3.0. Java 1.6

I need to access Active Directory via Java code. I read about several ways (Kerberos, LDAP)

Anyone could advice me on comfortable way of doing so? where could I have some full code examples,

thanks, ray.

28
votes
answers
28 views
+10

Separating war application name from war file name

Currently if i deploy a war file on tomcat named say myapp.war, I can access its url by http://localhost/myapp/MyServlet.

However what I want is to deploy a war with a version number in the war file name and still have the same url. For eg, I want to deploy myapp-1.1.0.war and still have the url be http://localhost/myapp/MyServlet

Of course I need to keep updating the war and the version number will keep changing, so I cant hardcode the war filename anywhere. Is there any setting in web.xml I can use to keep the same url for the app regardless of the war filename?

沙发
板凳
+80

您可以使用YOUR_WAR / META-INF / context.xml。以下是一個示例:

 &lt;?xml version =“1.0”encoding =“UTF-8”?&gt; &lt; Context antiJARLocking =“true”path =“/ MyServlet”/&gt;  
     
			
        

@Matthew Gillard據我所知,tomcat文檔說不要在Server.xml中放置Context元素。它們對META-INF / context.xml沒有任何問題。文檔甚至會告訴您context.xml的工作原理。從文檔:“可以顯式定義上下文元素:*在$ CATALINA_BASE / conf / context.xml文件中:Context元素信息將由所有webapps加載。” - Karthik Ramachandran 2011年5月3日21:03

我誤讀了嗎?“path”部分說:“除非在server.xml中靜態定義Context,否則不得設置此字段的值” - Matthew Gilliard 2011年5月3日21:08

不適用於Tomcat 7.0.11。 - 帕維爾11月30日在5:29

不適用於Tomcat 7.0.26 - Marcus Junius Brutus 2014年12月3日15:00

不適用於Tomcat 8.0.15 - JustinKSU 2014年12月26日21:01

地板
+40

使用 Maven 時,您可以通過執行以下操作來控制部署的路徑:

Tomcat的conf / tomcat-users.xml:

 &lt; tomcat-users&gt; &lt; role rolename =“manager-gui”/&gt; &lt; role rolename =“manager-script”/&gt; &lt; role rolename =“manager-jmx”/&gt; &lt; role rolename =“manager-status”/&gt; &lt; role rolename =“admin-gui”/&gt; &lt; role rolename =“admin-script”/&gt; &lt; user username =“root”password =“root”roles =“manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script”/&gt; &LT; / Tomcat的用戶&GT; < / code>  

?/ .m2 / settings.xml:

  ...&lt; server&gt; &LT; ID&GT; Tomcat的&LT; / ID&GT; &lt;用戶名&GT;根&LT; /用戶名&gt; &LT;密碼&GT;根&LT; /密碼&GT; &LT; /服務器&GT; ...   

pom.xml:

  ...&lt; modelVersion&gt; 4.0.0&lt; / modelVersion&gt; &LT;&的groupId GT; com。示例&LT; /&的groupId GT; &LT; artifactId的&GT; MYAPP&LT; / artifactId的&GT; &LT;版本&GT; 1.1.0&LT; /版本&GT; &LT;包裝和GT;戰爭&LT; /包裝&GT; ...&lt; build&gt; &LT;插件&GT; &LT;插件&GT; &LT;&的groupId GT; org.codehaus.mojo&LT; /&的groupId GT; &LT; 的artifactId&GT; Tomcat的行家-插件&LT; / artifactId的&GT; &LT;結構&gt; &lt;! - 在Tomcat7下面忽略/ html: - &gt; &LT; URL&GT; HTTP://服務器:8080 /經理/ HTML&LT; / URL&GT; &lt;! - 請參閱?/ .m2 / settings.xml中的服務器設置 - &gt; &LT;服務器&GT; Tomcat的&LT; /服務器&GT; &LT;路徑&GT; / myWebApp&LT; /路徑&GT; &LT; /結構&gt; &LT; /插件&GT; ....&lt; / plugins&gt; &LT; /構建&GT; ...   

首先啟動tomcat然後構建並部署應用程序..

  mvn clean install tomcat:deploy   

..它可以在 http:// server下訪問:

@nir感謝你的糾正 - Lorand Bendig於2014年8月19日22:09

4楼
+10

web.xml中沒有為此設置。我不相信有可能以交叉容器的方式在war文件中設置它 - 在規範中沒有提到它 - 所以每個容器以不同的方式做到這一點。 jboss-web.xml sun-web.xml context.xml 等。

5楼
+10

我更喜歡使用“ ## ”符號來記錄tomcat中* .war文件的版本。
例如:
myapp.war - &gt;
URL: http:// localhost:8080 / myapp / MyServlet
myapp ## 1.1.0 - &gt;
網址: http:// localhost:8080 / myapp / MyServlet (仍然相同,因為之後的所有符號“ ## ”被tomcat忽略了)

6楼
0
deployOnStartup和autoDeploy都是false 如果不遵循此規則,可能會導致雙重部署。

所以在我的情況下,我切換了 deployOnStartup autoDeploy 為false,所以我的WAR(egaWAR)沒有自動展開到webapps下的'a'目錄,而是自動展開到'b'目錄,由於這些設置:

 &lt; Host name = “localhost”appBase =“webapps”autoDeploy =“false”deployOnStartup =“false”unpackWARs =“true”deployIgnore =“$ {ignore.context}”&gt; &lt; Context docBase =“a”path =“/ b”/&gt; &LT; /主機&GT;   如果不遵循此規則,可能會導致雙重部署。  

所以在我的情況下,我切換了 deployOnStartup autoDeploy 為false,所以我的WAR(egaWAR)沒有自動展開到webapps下的'a'目錄,而是自動展開到'b'目錄,由於這些設置:

 &lt; Host name = “localhost”appBase =“webapps”autoDeploy =“false”deployOnStartup =“false”unpackWARs =“true”deployIgnore =“$ {ignore.context}”&gt; &lt; Context docBase =“a”path =“/ b”/&gt; &LT; /主機&GT;   如果不遵循此規則,可能會導致雙重部署。  

所以在我的情況下,我切換了 deployOnStartup autoDeploy 為false,所以我的WAR(egaWAR)沒有自動展開到webapps下的'a'目錄,而是自動展開到'b'目錄,由於這些設置:

 &lt; Host name = “localhost”appBase =“webapps”autoDeploy =“false”deployOnStartup =“false”unpackWARs =“true”deployIgnore =“$ {ignore.context}”&gt; &lt; Context docBase =“a”path =“/ b”/&gt; &LT; /主機&GT;   

所以在我的情況下,我將 deployOnStartup autoDeploy 都切換為false,因此我的WAR(egaWAR)沒有自動展開到webapps下的'a'目錄,但由於這些設置,轉而進入'b'目錄:

 &lt; Host name =“localhost”appBase =“webapps”autoDeploy =“false”deployOnStartup =“false”unpackWARs =“true “deployIgnore =”$ {ignore.context}“&gt; &lt; Context docBase =“a”path =“/ b”/&gt; &LT; /主機&GT;   

所以在我的情況下,我將 deployOnStartup autoDeploy 都切換為false,因此我的WAR(egaWAR)沒有自動展開到webapps下的'a'目錄,但由於這些設置,轉而進入'b'目錄:

 &lt; Host name =“localhost”appBase =“webapps”autoDeploy =“false”deployOnStartup =“false”unpackWARs =“true “deployIgnore =”$ {ignore.context}“&gt; &lt; Context docBase =“a”path =“/ b”/&gt; &LT; /主機&GT;   WAR)沒有自動展開到webapps下的'a'目錄,而是自動展開到'b'目錄,由於這些設置: 
 &lt; Host name =“localhost”appBase =“webapps “autoDeploy =”false“deployOnStartup =”false“unpackWARs =”true“deployIgnore =”$ {ignore.context}“&gt; &lt; Context docBase =“a”path =“/ b”/&gt; &LT; /主機&GT;   WAR)沒有自動展開到webapps下的'a'目錄,而是自動展開到'b'目錄,由於這些設置: 
 &lt; Host name =“localhost”appBase =“webapps “autoDeploy =”false“deployOnStartup =”false“unpackWARs =”true“deployIgnore =”$ {ignore.context}“&gt; &lt; Context docBase =“a”path =“/ b”/&gt; &LT; /主機&GT;  
     
			
        
52
votes
answers
22 views
+10

Real time updates from database using JSF/Java EE

I have one application running in the following environment.

  • GlassFish Server 4.0
  • JSF 2.2.8-02
  • PrimeFaces 5.1 final
  • PrimeFaces Extension 2.1.0
  • OmniFaces 1.8.1
  • EclipseLink 2.5.2 having JPA 2.1
  • MySQL 5.6.11
  • JDK-7u11

There are several public pages which are lazily loaded from the database. A few CSS menus are displayed on the header of the template page like displaying category/subcategory-wise featured, top seller, new arrival etc products.

The CSS menus are populated dynamically from the database based on various categories of products in the database.

These menus are populated on every page load which is completely unnecessary. Some of these menus require complex/expensive JPA criteria queries.

Currently the JSF managed beans that populate these menus are view scoped. They all should be application scoped, be loaded only once on application start up and be updated only when something in the corresponding database tables (category/subcategory/product etc) is updated/changed.

I made some attempts to understand WebSokets (never tried before, completely new to WebSokets) like this and this. They worked fine on GlassFish 4.0 but they don't involve databases. I'm still not able to understand properly how WebSokets work. Especially when database is involved.

In this scenario, how to notify the associated clients and update the above-mentioned CSS menus with the latest values from the database, when something is updated/deleted/added to the corresponding database tables?

A simple example/s would be great.

up vote 46 down vote accepted favorite
沙发
+460
+50

前言

在這個答案中,我將假設以下內容:

  • 您對使用&lt; p:push&gt; (我將保留中間的確切原因,您至少對使用新的Java EE 7 / JSR356 WebSocket API感興趣)。
  • 您想要一個應用程序作用域推送(即所有用戶)同時獲取相同的推送消息;因此您對會話不感興趣,也不會查看範圍推送。)
  • 您想直接從(MySQL)數據庫端調用push(因此您對此不感興趣)使用實體監聽器從JPA端調用push)。修改:無論如何,我將涵蓋這兩個步驟。步驟3a描述了DB觸發,步驟3b描述了JPA觸發。使用它們,或者不是兩者都使用它們!


    1。創建WebSocket端點

    首先創建一個 @ServerEndpoint 類,它基本上將所有websocket會話收集到應用程序範圍集中。請注意,在此特定示例中,這只能是 static ,因為每個websocket會話基本上都有自己的 @ServerEndpoint 實例(它們與servlet不同,因此無狀態)。 < pre> @ServerEndpoint(“/ push”)public class Push {private static final Set&lt; Session&gt; SESSIONS = ConcurrentHashMap.newKeySet(); @OnOpen public void onOpen(Session session){SESSIONS.add(session); } @OnClose public void onClose(Session session){SESSIONS.remove(session); public static void sendAll(String text){synchronized(SESSIONS){for(Session session:SESSIONS){if(session.isOpen()){session.getAsyncRemote()。sendText(text);

    上面的示例有一個額外的方法 sendAll(),它將給定的消息發送到所有打開的websocket會話(即應用程序作用域推送)。請注意,此消息也可以是JSON字符串。

    如果您打算將它們顯式存儲在應用程序範圍(或(HTTP)會話範圍內),然後你可以使用 ServletAwareConfig 示例356-serverendpo / 23405830#23405830“>這個答案您知道, ServletContext 屬性映射到JSF中的 ExternalContext#getApplicationMap()(並且 HttpSession 屬性映射到 ExternalContext#getSessionMap()< / code>)。


    2。在客戶端打開WebSocket並監聽它

    使用這段JavaScript打開websocket並監聽它:

      if(window.WebSocket){var ws = new WebSocket(“ws://example.com/contextname/push”); ws.onmessage = function(event){var text = event.data; 的console.log(文本); }; } else {//運氣不好。瀏覽器不支持它。考慮回到長期民意調查。//有關支持的瀏覽器的概述,請參見http://caniuse.com/websockets。//存在具有透明回退的jQuery WebSocket插件。}   

    截至目前,它只記錄推送的文本。我們想將此文本用作更新菜單組件的指令。為此,我們需要一個額外的&lt; p:remoteCommand&gt;

     &lt; h:form&gt; &lt; p:remoteCommand name =“updateMenu”update =“:menu”/&gt; &LT; /小時:形式&GT;   < p>想像一下,您通過 Push.sendAll(“updateMenu”)發送JS函數名作為文本,然後您可以按如下方式解釋並觸發它: 
      ws.onmessage = function(event){var functionName = event.data; if(window [functionName]){window [functionName](); }};   

    再次,當使用JSON字符串作為消息(您可以通過 $。parseJSON(event.data)解析時),可以實現更多動態。


    3a。 從數據庫端觸發WebSocket推送

    現在我們需要從數據庫端觸發命令 Push.sendAll(“updateMenu”)允許DB在Web服務上觸發HTTP請求的最簡單方法之一。一個簡單的vanilla servlet就足以像Web服務一樣:

      @WebServlet(“/ push-update-menu”)公共類PushUpdateMenu擴展HttpServlet {@Override protected void doGet(HttpServletRequest) request,HttpServletResponse response)拋出ServletException,IOException {Push.sendAll(“updateMenu”);   

    您當然有機會根據請求參數或路徑信息參數化推送消息(如有必要)。如果允許調用者調用此servlet,請不要忘記執行安全檢查,否則世界上除了DB本身之外的任何其他人都可以調用它。你可以檢查一下來電者 例如,如果DB服務器和Web服務器都在同一台機器上運行,那麼IP地址就很方便。

    為了讓DB在該servlet上觸發HTTP請求,您需要創建一個可重用的存儲過程,它基本上調用操作系統特定的命令來執行HTTP GET請求,例如 curl MySQL本身不支持執行特定於操作系統的命令,因此您需要首先安裝用戶定義的函數(UDF)。 mysqludf.org ,您可以找到一堆 SYS 是我們感興趣的。它包含我們需要的 sys_exec()函數。安裝完成後,在MySQL中創建以下存儲過程:

      DELIMITER // CREATE PROCEDURE menu_push()BEGIN SET @result = sys_exec('curl http ://example.com/contextname/push-update-menu'); 結束// DELIMITER;   

    現在您可以創建將調用它的插入/更新/刪除觸發器(假設表名稱為 menu ):

     創建TRIGGER after_menu_insert後插入菜單FOR EACH ROW CALL menu_push();   
     創建TRIGGER after_menu_update更新ON菜單之後每個行調用menu_push();   < pre class =“lang-sql prettyprint-override”> 創建TRIGGER after_menu_delete刪除ON菜單後每個行調用menu_push();   


    3b。從JPA端觸發WebSocket推送

    如果您的需求/情況允許僅偵聽JPA實體更改事件,因此對DB的外部更改需要覆蓋,然後您可以而不是如步驟3a中所述的數據庫觸發器也只使用JPA實體更改偵聽器。您可以通過 @Entity 類上的 @EntityListeners 註釋註冊它:

      @Entity @EntityListeners(MenuChangeListener.class)public class Menu {// ...} < / code>  

    如果您碰巧使用單個Web配置文件項目,其中所有內容(EJB / JPA / JSF)在同一個項目中被拋出,那麼您可以直接調用 Push.sendAll( “updateMenu”)在那裡。

      public class MenuChangeListener {@PostPersist @PostUpdate @PostRemove public void onChange(菜單菜單){Push.sendAll(“updateMenu”); 然而,在“企業”項目中,服務層代碼(EJB / JPA / etc)通常在EJB項目中分離,而Web層代碼(JSF / Servlets / WebSocket / etc)保存在Web項目中。EJB項目應該對web項目有沒有單一的依賴關係。在這種情況下,你最好發一個CDI  Event ,而不是Web項目可以 @Observes  
      public class MenuChangeListener {/ /已註釋,因為它在當前的GF / WF版本中已被破壞。// @Inject // private Event&lt; MenuChangeEvent&gt; 事件; @Inject私有BeanManager beanManager; @PostPersist @PostUpdate @PostRemove public void onChange(菜單菜單){//取消註釋,因為它在當前的GF / WF版本中被破壞了。// event.fire(new MenuChangeEvent(menu)); beanManager.fireEvent(new MenuChangeEvent(menu)); }   

    (注意註釋;注入CDI 事件 在當前版本(4.1 / 8.2)中,GlassFish和WildFly都被破壞了; 解決方法是通過 BeanManager 來觸發事件; 如果這仍然不起作用,CDI 1.1替代方案是 CDI.current()。getBeanManager()。fireEvent(new MenuChangeEvent(menu))

      public class MenuChangeEvent {private Menu menu; public MenuChangeEvent(菜單菜單){this.menu = menu; } public Menu getMenu(){return menu; }   

    然後在Web項目中:

      @ApplicationScoped public class Application {public void onMenuChange(@Observes MenuChangeEvent event){Push.sendAll( “updateMenu”); } < / code>  

    更新:2016年4月1日(上述答案後半年), OmniFaces 在版本2.3中引入了 &lt; o:socket&gt; ,這應該使這一切不那麼迂迴。即將推出的JSF 2.3 &lt; f:websocket&gt; 主要基於&lt; o:socket&gt; 另請參見服務器如何將異步更改推送到JSF創建的HTML頁面? 在2016年4月1日(上述答案後半年), OmniFaces 推出2.3版 &lt; o:socket&gt; 應該使這一切變得不那麼迂迴。即將推出的JSF 2.3 &lt; f:websocket&gt; 主要基於&lt; o:socket&gt; 另請參見服務器如何將異步更改推送到JSF創建的HTML頁面? 在2016年4月1日(上述答案後半年), OmniFaces 推出2.3版 &lt; o:socket&gt; 應該使這一切變得不那麼迂迴。即將推出的JSF 2.3 &lt; f:websocket&gt; 主要基於&lt; o:socket&gt; 另請參見服務器如何將異步更改推送到JSF創建的HTML頁面? a href =“http://showcase.omnifaces.org/push/socket”rel =“noreferrer”> &lt; o:socket&gt; 應該使這一切變得更加迂迴。即將推出的JSF 2.3 &lt; f:websocket&gt; 主要基於&lt; o:socket&gt; 另請參見服務器如何將異步更改推送到JSF創建的HTML頁面? a href =“http://showcase.omnifaces.org/push/socket”rel =“noreferrer”> &lt; o:socket&gt; 應該使這一切變得更加迂迴。即將推出的JSF 2.3 &lt; f:websocket&gt; 主要基於&lt; o:socket&gt; 另請參見服務器如何將異步更改推送到JSF創建的HTML頁面?

如果需要對DB的外部更改進行說明,我在第一次評論您的問題時就問過您。你回答“兩種方式”,所以我明白你也想要覆蓋它。JPA實體監聽器不足以涵蓋這一點,因為當您從應用程序外部操作數據庫時,它們不會得到通知(例如,通過某些數據庫管理工具或甚至是共享同一數據庫的其他應用程序)。 - BalusC 2014年10月12日18:44

我擴展了步驟3b的答案,以防用戶只對JPA實體監聽器感興趣。 - BalusC 2014年10月13日7:49

在大多數情況下,我依賴於JPA方面和CDI事件,很高興知道它不僅僅限於那一方,UDF似乎很有希望在一個數據庫上可能有多個應用程序!這個shoudl是博客文章tho :) - Hatem Alimam 2014年10月13日20:35

你已經提到過他可能對p:push不感興趣,你會在中間留下確切的理由嗎?你認為p:push不合適的原因是什麼? - Hatem Alimam 2014年10月13日20:47

+50

由於您使用的是Primefaces和Java EE 7,因此應該很容易實現:

使用Primefaces Push(例如 http://www.primefaces.org/showcase/push/notify.xhtml

  • 創建一個收聽的視圖Websocket端點
  • 創建一個數據庫監聽器,在數據庫更改時生成CDI事件
    • 事件的有效負載可以是最新數據的增量,也可以只是更新信息
    • 通過Websocket將CDI事件傳播到所有客戶端
    • 客戶端更新數據

      希望這會有所幫助如果您需要更多詳情請問

      此致

+10

PrimeFaces具有輪詢功能,可自動更新組件。在以下示例中,&lt; h:outputText&gt; 將每3秒由&lt; p:poll&gt; 自動更新。

如何通知關聯的客戶端並使用數據庫中的最新值更新上述CSS菜單?

創建一個監聽器方法,如 process()來選擇你的菜單數據。&lt; p:poll&gt; 將自動更新您的菜單組件。

 &lt; h:form&gt; &lt; h:outputText id =“count”value =“#{AutoCountBean.count}”/&gt; &LT ;!  - 替換菜單組件 - &gt; &lt; p:poll interval =“3”listener =“#{AutoCountBean.process}”update =“count”/&gt; &LT; /小時:形式&GT;   
  @ManagedBean @ViewScoped公共類AutoCountBean實現Serializable {private int count; public int getCount(){return count; public void process(){number ++; //從db中替換您的選擇數據。}}   @ManagedBean @ViewScoped公共類AutoCountBean實現Serializable {private int count; public int getCount(){return count; public void process(){number ++; //從db中替換您的選擇數據。}}   @ManagedBean @ViewScoped公共類AutoCountBean實現Serializable {private int count; public int getCount(){return count; public void process(){number ++; //從db中替換您的選擇數據。}}  
     
			
        

對於觸發在指定時間點發生的定期操作非常有用。在這種情況下,它不像定期發生的長輪詢。此處的操作不依賴於計時器。它應該發生,只有當其他事情發生或從未發生過。 - 小小的2014年9月22日9:00

16
votes
answers
13 views
+10

Why does getRealPath() return null when deployed with a .war file? [duplicate]

This question already has an answer here:

getRealPath() is returning the actual path in the local system, but returns null when deployed with a .war file.

<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=ISO-8859-1" %> 
<%
int iLf = 10;
char cLf = (char)iLf;
String a= application.getResource("/");
//String myfile = application.getRealPath("/")+ "generate.xml";
//String myfile = request.getContextPath()+"generate.xml";
//String myfile = request.getRealPath("/")+"generate.xml";

out.println(myfile);    
File outputFile = new File(myfile);
outputFile.createNewFile();
FileWriter outfile = new FileWriter(outputFile);
outfile.write(" <?xml version='1.0' encoding='UTF-8'?> "+cLf);
outfile.write(" <playlist version='1' xmlns = 'http://xspf.org/ns/0/' > " +cLf);
outfile.write(" <title>My Band Rocks Your Socks</title> "+cLf); 
outfile.write("<trackList>"+cLf); 
%>
 <%! String[] sports; %>
 <%
    sports = request.getParameterValues("sports");

    out.println("<html><body><h1>hello</h1></body></html>");

    if (sports != null)
    { 
         for (int i = 0; i < sports.length; i++)
         { 
              // outfile.writeln (sports[i]); 
              String total=sports[i];
              String[] sa=total.split("[,]");
              // String[] sub=new String();
              outfile.write("<track>"+cLf);
              for (int j=0;j<sa.length;j++)
              {
                // outfile.writeln(sa[j]);
                // outfile.writeln("sa["+j+"]="+sa[j]);
                if( j == 0)
                {
                     outfile.write("<location>" + sa[0] +"</location>"+cLf); 
                }
                else if (j == 1)
                     {
                        outfile.write("<image>" + sa[1] +"</image>"+cLf); 
                     }
                     else if( j==2)
                          {
                            outfile.write("<title>" + sa[2] +"</title>"+cLf);
                          }

               }// end of inner for loop()       
               outfile.write("</track>"+cLf);
         //outfile.writeln();
      }// end of outer for()
    } 
    //else outfile.writeln ("<b>none<b>");

  outfile.write(" </trackList> "+cLf);
  outfile.write(" </playlist> "+cLf);
  outfile.close();

  %>
<object type="application/x-shockwave-flash" width="400" height="170"
          data="xspf_player.swf?playlist_url=generate.xml">
          <param name="movie" value="xspf_player.swf?playlist_url=generate.xml" />

</object>

Can anyone provide me with an alternative for this? It would be very helpful if you showed some sample code too.

沙发
+60

你使用Weblogic嗎?

如果是 - 那麼這是一個Weblogic問題,您可以在Weblogic管理控制台中修復 - &gt; Domain-&gt; Web應用程序 - 單擊複選框“已存檔的實際路徑” “。

請參閱: http:// ananthkannan。 blogspot.com/2009/12/servletcontextgetrealpath-returns-null.html

板凳
+30

這也解決了這個問題:

weblogic.xml

 &lt;?xml version ='1.0'coding ='windows-1252'?&gt; &lt; weblogic-web-app xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”xsi:schemaLocation =“http://www.bea.com/ns/weblogic/weblogic-web -app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd“xmlns =”http://www.bea.com/ns/weblogic/weblogic -web應用內“&GT; &LT;容器描述符GT; &lt;真&LT;啟用索引目錄&gt /&GT啟用索引目錄; &LT;顯示歸檔的啟用實時的路徑&GT;真&LT; /顯示啟用存檔實時的路徑&GT; &LT; /容器描述符GT; &LT;虛擬目錄映射&GT; &lt;局部路徑&GT; bla.war&LT; /本地路徑&GT; &LT; URL模式&GT * LT; / url-pattern的&GT; &LT; /虛擬目錄映射&GT; &LT;上下文根&GT; BLA&LT; /上下文根&GT;   

地板
+20

我不相信你可以做你想做的事情。

你應該使用getResource從war文件中讀取xml文件(這也可以在沒有戰爭的情況下運行)

  servletContext.getResourceAsStream(“/ generate.xml”)< / code>  

前導斜杠取決於generate.xml的存儲位置。

classloader和servletcontext可能對什麼是/generate.xml有不同的想法 - 一個是通過類路徑查找,另一個是通過應用程序上下文(不是來自WEB-INF /類,而是來自WAR的根)。所以正確的方法是使用ServletContext.getResourceAsStream。 - 弗拉基米爾Dyuzhev 09年2月11日在15:10

很公平,我編輯。 - 克羅森沃爾德2009年2月11日15:29

回答問題是主要目標。這個答案沒有提供任何有效的解決方案! - Stephan 2016年10月5日10:38

4楼
+20

我也有同樣的問題。調用getRealPath()在部署到獨立服務器時返回null。在搜索了一會兒之後,我找到了解決方案,它不在代碼中。它位於您的Web服務器的配置中。

對我來說,這是Weblogic 10.3,你轉到Home - - Configuration - Web Application,將Archived Real Path Enabled設置為true。
重啟服務器,一切正常。

希望這個幫助,問候。

5楼
+20

如果你想寫入

使用

  this.getClass()。getResource(“/”)。getPath();   

獲取路徑

謝謝。哈哈,我花了太多時間尋找這個。 - adprocas於2017年3月23日13:57

6楼
+10

注意 context.getRealPath()在有用戶權限問題時可以返回null,檢查在哪個用戶下運行的Web服務器。

7楼
0

以下修復程序對我來說很好。

  //我正在使用Struts2 ServletContext sc =(ServletContext)ac.get(StrutsStatics.SERVLET_CONTEXT); fileInputStream = sc.getResourceAsStream(“test.xls”);   

在部署war文件後,我可以從上下文路徑中獲取文件。

8楼
-10

以下解決了我的問題。

  public EHWInit(){String resetRootPath =“”; 嘗試{resetRootPath = this.getClass()。getResource(“/”)。getPath(); boolean isWinOS = System.getProperty(“os.name”)。startsWith(“Windows”); if(isWinOS){resetRootPath = resetRootPath.substring(1,resetRootPath.lastIndexOf(“chucec”));} else {resetRootPath = resetRootPath.substring(0,resetRootPath.lastIndexOf(“chucec”));} resetRootPath = resetRootPath.replace (“%20”,“”); System.out.println(“EHWInit#75:resetRootPath =”+ resetRootPath);   

當您嘗試通過 this.getClass()。getResource(“/”)獲取 getRealPath 時。當操作系統是Windows時,getPath(),您可能會得到如下字符串:

 EHWInit#73:getPath = / C:/ Program%20Files%20(x86)/ Apache%20Software %20Foundation / Tomcat%208.5 / webapps / chucec / WEB-INF / classes /  

因此,你需要對返回的字符串做一些額外的工作。此外,如果你想獲得 getRealPath 按要求。您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   / strong>當操作系統是Windows時,您可能會得到如下字符串: 
 EHWInit#73:getPath = / C:/ Program%20Files%20(x86)/ Apache%20Software%20Foundation / Tomcat %208.5 / webapps / chucec / WEB-INF / classes /  

因此,您需要對返回的字符串做一些額外的工作。此外,如果您想通過請求獲取 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   / strong>當操作系統是Windows時,您可能會得到如下字符串: 
 EHWInit#73:getPath = / C:/ Program%20Files%20(x86)/ Apache%20Software%20Foundation / Tomcat %208.5 / webapps / chucec / WEB-INF / classes /  

因此,您需要對返回的字符串做一些額外的工作。此外,如果您想通過請求獲取 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   當操作系統是Windows時,您可能會得到如下字符串: 
 EHWInit#73:getPath = / C:/ Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/ webapps / chucec / WEB-INF / classes /  

因此,你需要對返回的字符串做一些額外的工作。此外,如果你想通過請求得到 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   當操作系統是Windows時,您可能會得到如下字符串: 
 EHWInit#73:getPath = / C:/ Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/ webapps / chucec / WEB-INF / classes /  

因此,你需要對返回的字符串做一些額外的工作。此外,如果你想通過請求得到 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   然後你可能得到一個如下字符串: 
 EHWInit#73:getPath = / C:/ Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/webapps/chucec/WEB -INF / classes /  

因此,你需要對返回的字符串做一些額外的工作。此外,如果你想通過請求得到 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   然後你可能得到一個如下字符串: 
 EHWInit#73:getPath = / C:/ Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/webapps/chucec/WEB -INF / classes /  

因此,你需要對返回的字符串做一些額外的工作。此外,如果你想通過請求得到 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   getPath = / C:/ Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/webapps/chucec/WEB-INF/classes/  

因此,你需要做一些額外的工作返回的字符串。此外,如果你想通過請求獲得 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   getPath = / C:/ Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/webapps/chucec/WEB-INF/classes/  

因此,你需要做一些額外的工作返回的字符串。此外,如果你想通過請求獲得 getRealPath 您可以替換如下代碼:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   因此,你需要對返回的字符串做一些額外的工作。此外,如果你想通過請求得到 getRealPath 您可以替換如下代碼: 
  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   因此,你需要對返回的字符串做一些額外的工作。此外,如果你想通過請求得到 getRealPath 您可以替換如下代碼: 
  public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);   public void resetSystemPath(HttpServletRequest paramHttpServletRequest){// String str = paramHttpServletRequest.getRealPath(“/”); HttpSession session = paramHttpServletRequest.getSession(true); String str = session.getServletContext()。getRealPath(“/”); 的System.out.println(“getRealPath:”+ STR);  
     
			
        
51
votes
answers
10 views
+10

Absence of @Temporal annotation in hibernate

What if we use

@Column(name="birth_date", nullable=false, length=19)
public Date getBirthDate() {
    return this.birthDate;
}

instead of

@Temporal(TemporalType.TIMESTAMP)
@Column(name="birth_date", nullable=false, length=19)
public Date getBirthDate() {
    return this.birthDate;
}

Are there any side effects if we use date column property without @Temporal annotation?

up vote 29 down vote accepted favorite
沙发
+290
+50

我設法找到的只有一些文檔:

在普通的Java API中,時間的時間精度未定義處理時態數據時,您可能希望描述數據庫中的預期精度。時態數據可以具有DATE,TIME或TIMESTAMP精度(即實際日期,僅時間或兩者)。使用@Temporal註釋來微調它。

來自 2.2.2.1。聲明基本屬性映射

可能

+1 - 如果沒有指定@Temporal,我也沒有找到更多可以討論Hibernate會做什麼的片段。就像添加一樣 - EclipseLink甚至不允許您不定義時間精度。我寧願定義你期望的精確精度。 - Piotr Nowicki 2011年12月12日12:38

+220

我意識到這個問題已經得到了回答,但我們今天仍在努力解決這個問題,所以我想為未來偶然發現這一點的人提供更多見解。

如果不使用時態註釋,則將Oracle 11g與版本11驅動程序一起使用,那麼Oracle中的每個日期,時間和時間戳數據類型都將在運行時映射到代碼中的時間戳。功能上這很好,但這導致我們嚴重的性能問題。這是因為我們將DATE類型作為複合主鍵的一部分。此列是索引的前導列以及我們用於分區的列。當驅動程序嘗試在where子句中使用此列保留記錄時,Oracle將執行DB中數據從DATE到TIMESTAMP的類型轉換。這使得索引無用,性能也很糟糕。< / p>

長篇故事,請添加此註釋,以免您準備付出代價。

+1回答:) - Nandkumar Tekale 12年7月17日在6:35

用實時例子很好的解釋。TY! - 暗黑破壞神2016年7月26日12:04

0
votes
answers
34 views
+10

後臺線程

0

我正在使用Websphere Application Server創建一個典型的Web應用程序,其中UI是JSP,有一個Controller和一個會話EJB和一個數據庫。我實現了一個通知系統,作爲一個單獨的線程在後臺運行。爲此,我使用了WorkManager。後臺線程

我的問題是,我想啓動WorkManager,而不必爲每個由不同用戶啓動的每個並行會話創建會話或EJB實例。它不應該基於會話。 現在,WorkManager線程在EJB實例化時啓動,所以如果有3個連接,則有3個WorkManager實例。

單會話bean會是一個好主意嗎?或者有什麼地方可以放置一個將被調用的'main()'方法,或者類似的東西?

任何想法,將不勝感激。

沙发
0
1

我認爲有以下幾個選項:

  • 使用servlet上下文偵聽提交工作(當WAR模塊啓動,這將被調用/停止)。
  • 使用啓動Bean(WebSphere特定API),在應用程序啓動/停止時調用一次。
  • 使用引用計數方法記錄EJB實例的數量。您在創建第一個實例時提交工作(並在最後一個實例被銷燬時停止工作)。請注意,這會延遲工作的開始,直到第一次請求EJB。
  • 在WebSphere 8(支持Java EE 6)中,您可能使用單例會話bean。
54
votes
answers
5 views
+10

Batch inserts using JPA EntityManager

Is there a way where we can use batch inserts using JPA EntityManager. I know there is no direct way to achieve this but there must be some way to achieve this mechanism.

Actually, for every insert operation it's taking me 300ms which I want to reduce using batch inserts instead of single inserts.

Here's code I am using currently executing for single inserts

        @PersistenceContext(unitName = "testing")
        EntityManager eM;

        Query querys = this.eM.createNativeQuery(insertQuery);
        for (String s : someList) {
            //setting parameters
            querys.executeUpdate();
        }

Thanks in advance.

up vote 12 down vote accepted favorite
沙发
+120
+50

可以使用JPA執行批量寫入,但它高度依賴於持久性提供程序,數據庫和JDBC驅動程序的特定實現。例如,文章解釋瞭如何使用EclipseLink JPA 2.3和Oracle數據庫啟用批量寫入(優化#8)。查看特定環境中的類似配置參數。

嗨,我正在使用org.eclipse.persistence.jpa.PersistenceProvider。如果使用批量插入物有任何限制,請告訴我。 - 於12月14日14:26離開

@Rana全部在鏈接文章中,您必須編輯persistence.xml文件並添加類似 。請花點時間先閱讀這篇文章。 - ÓscarLópez於2012年5月14日14:30

嗨,我已經添加了,我正在尋找有關我需要使用此聲明觀察的任何陷阱的信息。謝謝。 - 於12月14日14:39離開

+230

根據事務是否包含循環,批處理通常已在您的情況下發生。

JPA將在其L1緩存中收集所有更新,並且通常在批處理時將所有更新寫入數據庫。事務提交。這與在JDBC中進行批處理並沒有什麼不同,在您調用更新方法之前,您添加的每個批處理項目也暫時存在於內存中。

可能存在的問題是您沒有對JPA的硬性保證確實這個批處理完成,如果在事務提交或達到閾值時這樣做,但我發現在實踐中幾乎在所有情況下,特別是在涉及這種簡單更新循環的情況下,它確實進行了批處理。

一個問題是,即使JPA確實已經進行批處理,您仍然可能希望控制批量大小。通過其他答案鏈接的文章為此提供了非常有用的信息。

最後,您應該知道您的L1緩存在循環中不斷增長,因此如果更新的數量非常大,請定期清除它。或者,如果您的業務邏輯可以維持它,請在多個事務中進行部分更新。例如,交易1中的項目0到100.000,交易2中的100.001到200.000等等。 如果您的業務邏輯可以支持它,請在多個事務中進行部分更新。例如,交易1中的項目0到100.000,交易2中的100.001到200.000等等。 如果您的業務邏輯可以支持它,請在多個事務中進行部分更新。例如,交易1中的項目0到100.000,交易2中的100.001到200.000等等。

嘿我現在使用了spring數據jpa,所以你的意思是如果我在方法中的循環中更新對象並且這個方法被@Transactional標記,它將自動批量更新,如jdbc批量更新。 - zhuguowei 2015年11月30日4:26

+160

我知道這是一個相當古老的問題,並且接受了答案。儘管如此,我想對這個非常具體的主題“JPA批量插入”給出新的答案。

  @PersistenceContext private EntityManager entityManager; @Value(“$ {hibernate.jdbc.batch_size}”)private int batchSize; public&lt; T extends MyClass&gt; 收集和LT; T&GT; bulkSave(Collection&lt; T&gt; entities){final List&lt; T&gt; savedEntities = new ArrayList&lt; T&gt;(entities.size()); int i = 0; for(T t:entities){savedEntities.add(persistOrMerge(t)); 我++; if(i%batchSize == 0){//刷新一批插入並釋放內存。entityManager.flush(); entityManager.clear(); 返回savedEntities; } private&lt; T擴展了MyClass&gt; T persistOrMerge(T t){if(t.getId()== null){entityManager.persist(t); 返回; } else {return entityManager.merge(t); }   

來源: http://frightanic.com/software-發展/ JPA分批插入/

我想我們需要在最後再次flush()和clear()以保存任何未完成批量大小的剩餘對象? - Ram Patra 2017年1月25日15:45

聽起來沒錯,謝謝@RamPatra。 - MarcelStör於2017年1月25日21:57

+30

JPA本身沒有任何批量設置。但是,有一些依賴於實現的設置。以下是hibernate的示例