我正在使用Spring MVC编写Java Web应用程序.我有一个后台进程通过数据库查找必须通过电子邮件发送给我的用户的通知.这些电子邮件消息需要包含应用程序的超链接.这似乎是一个相当常见的网络应用程序模式,但我遇到了麻烦.
如何使用服务器名称和上下文路径派生应用程序的完全限定URL?我无法访问HttpServletRequest中的任何方法,因为我将其作为后台进程运行,而不是响应Web请求.我能做的最好的就是访问ServletContext.
目前我将基本URL放入配置文件并在启动时读取它,但是此应用程序将获得许可并部署到客户的应用程序服务器,如果可能,我希望他们不必手动配置它.
我有一个Web应用程序,它依赖于在安装后配置的一些资源和参数,如JDBC连接.
我提出的是在部署应用程序时提供由Tomcat META-INF/context.xml复制[engine-name]/[server-name]/[app-name].xml的内容.这样我所提供的是一个war文件,可以复制到appBase文件夹(webapps).Tomcat的文档说如果有这样的文件,它将不会被覆盖,这真的很棒,因为部署后所做的更改不会丢失.
但是这里有一个微妙的问题:由于我们通过复制到webapps目录来部署应用程序,因此Tomcat将首先卸载现有应用程序以及配置文件.这样,配置文件将被丢失/覆盖,这是不可取的.据我所知,Tomcat 不会修改此行为.
问题是:有没有办法通过以Tomcat不会删除现有配置文件的方式安装应用程序来解决此问题.或者,有更好的方法来打包应用程序吗?
请注意,我们不希望将autoDeploy设置为false,并且我们不能使用人工干预进行安装(使用Tomcat Manager Web应用程序排除).
如果我从.war文件中获取配置文件并将其单独复制[engine-name]/[server-name]/[app-name].xml,Tomcat仍会将其与我的应用程序关联,并在复制新的.war文件后将其删除.
另一个假设是:我们事先并不知道配置的值.我们将仅提供样本配置(占位符,如果您愿意),而实际配置将在稍后的某个时间执行(不一定在安装时间内).
谢谢
最近我在按功能打包java代码时遇到了这个javalobby帖子http://java.dzone.com/articles/how-changing-java-package.
我喜欢这个想法,但我对这种方法的问题很少.我问了我的问题,但没有得到满意的答复.我希望StackOverflow上的某个人可以澄清我的问题.
我喜欢逐个功能的想法,它可以大大减少编码时移动包的时间,所有相关的东西都在一个地方(包).但是不同包中的服务之间的交互呢?
假设我们正在构建一个博客应用程序,我们将所有与用户相关的操作(控制器/服务/存储库)放在com.mycompany.myblog.users包中.并且包中的所有博客相关操作(控制器/服务/存储库)com.mycompany.myblog.posts.
现在我想显示用户个人资料以及他发布的所有帖子.我应该叫myblog.posts.PostsService.getPostsByUser(userId)从myblog.users.UserController.showUserProfile()?
包之间的耦合怎么样?
无论我在哪里阅读有关逐个功能的内容,每个人都说这是一个很好的做法.那么为什么许多书籍作者甚至框架都鼓励按层分组呢?只是好奇知道:-)
我知道有很多文章解释了如何在Java EE中使用CDI,但我无法弄清楚它实际带来了什么优势.例如,假设我有一个当前使用Foo实例的类.我也许会这样做
Foo myFoo = new Foo();
Run Code Online (Sandbox Code Playgroud)
要么
// Better, FooFactory might return a mock object for testing
Foo myFoo = FooFactory.getFoo();
Run Code Online (Sandbox Code Playgroud)
我一直在读CDI,我可以这样做:
@Inject
Foo myFoo;
Run Code Online (Sandbox Code Playgroud)
但为什么这比以前的工厂方法更好?我假设还有一些其他用例,我不知道,但我无法识别这一点.
如果我理解了下面的响应,那么概念就是DI框架充当集中配置的主对象工厂.这是一个合理的解释吗?
更新
我从那时起开始学习Spring,现在这更有意义了.下面的段落取自Spring in Practice,以一个AccountService类为例,该类反过来使用了一个实例AccountDao.我为长篇报道道歉,但我认为它真正解释了为什么注入资源提供了超过标准初始化的东西.
您可以使用new关键字构造AccountService,但是服务层对象的创建很少是如此简单.它们通常依赖于DAO,邮件发件人,SOAP代理等等.您可以在AccountService构造函数中(或通过静态初始化)以编程方式实例化每个依赖项,但这会导致硬件依赖性和级联更改,因为它们已被换出.
此外,您可以在外部创建依赖项,并通过setter方法或构造函数参数在AccountService上设置它们.这样做可以消除硬内部依赖关系(只要它们通过接口在AccountService中声明),但是你到处都有重复的初始化代码.以下是如何创建DAO并以Spring方式将其连接到AccountService:
<bean id="accountDao" class="com.springinpractice.ch01.dao.jdbc.JdbcAccountDao"/>
<bean id="accountService"
class="com.springinpractice.ch01.service.AccountService">
<property name="accountDao" ref="accountDao"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
如上所述配置bean后,您的程序现在可以AccountService从Spring ApplicationContext 请求一个实例,Spring DI框架将实例化需要实例化的所有内容.
我写了一个JAX-RS的附加内容,并将Java EE 6 API作为Maven依赖项包含在内.
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
然后我有一个小测试用例:
@Test
public void testIsWriteable() {
class SpecialViewable extends Viewable {
public SpecialViewable() {
super("test");
}
}
FreeMarkerViewProcessor processor = new FreeMarkerViewProcessor(null);
assertTrue(processor.isWriteable(SpecialViewable.class, null, null,
MediaType.WILDCARD_TYPE));
}
Run Code Online (Sandbox Code Playgroud)
但是我收到一个错误:
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/ws/rs/core/MediaType
...
Run Code Online (Sandbox Code Playgroud)
如果我将Jersey包含为JAX-RS实现而不是Java EE API,那么一切都很好.
感谢BalusC的暗示,我知道我猜到了什么:Java EE 6只是一个没有方法体的API: 来自java.net博客
您可以使用此jar编译代码,但当然您无法使用它运行应用程序,因为它只包含Java EE 5 API并且不包含任何方法体.如果你试图运行,你会得到这个例外:
线程"main"中的异常java.lang.ClassFormatError:类文件javax/mail/Session中非本地或抽象的方法中的Absent Code属性
为了执行Java EE 5应用程序,您仍然需要Java EE 5容器,例如GlassFish应用程序服务器.
我试图用test范围添加Jersy,但它没有用.
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version> …Run Code Online (Sandbox Code Playgroud) 今天我读到了Restful服务.基本上我所理解的是Restful webservices将在HTTP请求方法上工作,而不是普通的webservice将在SOAP请求上工作.
什么是Restful服务需要,因为普通的servlet也可以在HTTP方法上工作?
在我很少成功使用的项目中
@PersistenceUnit(unitName = "MiddlewareJPA")
EntityManagerFactory emf;
...
EntityManager entityManager = emf.createEntityManager();
Run Code Online (Sandbox Code Playgroud)
获取EntityManager数据库连接,但几天前我试图将我的项目移动到Jboss EAP 6.2它无法创建EntityManager.我在Google上搜寻它,我发现,我应该尝试改变@PersistenceUnit,以
@PersistenceContext(unitName = "MiddlewareJPA")
private EntityManager entityManager;
Run Code Online (Sandbox Code Playgroud)
获取EntityManager.它工作但我不知道为什么.有什么区别bettween PersistenceUnit和PersistenceContext?每个人的利弊是什么?我们应该在哪里使用其中一个?
我从服务器收到以下错误响应.
HTTP状态500 -
类型异常报告
信息
description服务器遇到内部错误(),导致无法完成此请求.
例外
javax.servlet.ServletException:java.lang.UnsupportedOperationException:尝试序列化java.lang.Class:org.hibernate.proxy.HibernateProxy.忘了注册一个类型适配器?
根本原因
java.lang.UnsupportedOperationException:尝试序列化java.lang.Class:org.hibernate.proxy.HibernateProxy.忘了注册一个类型适配器?
从Java调试器:
org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer@7632012e
Run Code Online (Sandbox Code Playgroud)
我正在使用Gson将我的Java对象转换为JSON.下面我贴了一些代码.
这是我的资源:
@Stateless
@LocalBean
@Path("/autos")
@Produces(MediaType.APPLICATION_JSON)
public class AutoResource {
@EJB
private CarAssembler warehouse;
@Context
private UriInfo uriInfo;
@GET
public Response allAutos() {
// Building a context, lots of code...
// Creating a Gson instance and configures it...
final Auto auto = warehouse.list(context);
final String autoJson = gson.toJson(auto);
return Response.ok(autoJson).build();
}
}
Run Code Online (Sandbox Code Playgroud)
CarAssembler只是一个调用存储库的服务.我没有在这里粘贴服务代码.
库:
@Override
public Question findById(final int id, final FetchType fetchType) {
final Auto question = …Run Code Online (Sandbox Code Playgroud) 我的web.xml看起来像:
<security-constraint>
<web-resource-collection>
<web-resource-name>app</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Role</role-name>
</auth-constraint>
</security-constraint>
Run Code Online (Sandbox Code Playgroud)
这保护每一方免受授权,但我想要排除/信息.这可能吗 ?