java空间中似乎有一种趋势,即不再以war文件(或ear文件)的形式将java Web应用程序部署到java servlet容器(或应用程序服务器),而是将应用程序打包为可执行jar.像jetty这样的嵌入式servlet/HTTP服务器.我的意思是,更新的框架影响新应用程序的开发和部署方式,而不是如何将应用程序交付给最终用户(因为,例如,我知道Jenkins使用嵌入式容器,非常容易抓住和去).采用可执行jar选项的框架示例: Dropwizard,Spring Boot和Play (它不是在servlet容器上运行,而是嵌入了HTTP服务器).
我的问题是,来自我们已经将我们(直到这一点,主要是Struts2)应用程序部署到单个tomcat应用程序服务器的环境,如果我们计划使用嵌入式容器方法,需要做出哪些更改,最佳实践或注意事项?目前,我们在单个tomcat服务器上运行大约10个自行开发的应用程序,对于这些小型应用程序,共享资源并在一台服务器上进行管理的能力很不错.我们的应用程序无意分发给最终用户以在其环境中运行.但是,如果我们决定利用更新的Java框架,那么这种方法会改变吗?越来越多地使用云部署(例如Heroku)刺激了对可执行jar的转变?
如果您有使用Play风格的部署管理多个应用程序而不是单个应用程序服务器上的传统war文件部署的经验,请分享您的见解.
我一直在调查使用JasperReports(6.0.0)和Spring MVC(4.1.3)来生成PDF报告.Spring充斥着"Spring特定"方式与JasperReports集成以生成PDF:
JasperReportsPdfView JasperReportsMultiFormatView JasperReportsViewResolver 我努力在网上找到好的,完整的例子,并想分享我的发现(见下面的答案).
随意添加与"如何将JasperReports与Spring4集成"相关的其他方法和/或改进?
使用Spring Data JPA可以通过示例进行查询,其中特定实体实例用作搜索条件吗?
例如(没有双关语),如果我有一个Person看起来像这样的实体:
@Entity
public class Person {
private String firstName;
private String lastName;
private boolean employed;
private LocalDate dob;
...
}
Run Code Online (Sandbox Code Playgroud)
我可以找到所有在1977年1月1日出生的史密斯姓氏的雇员,举个例子:
Person example = new Person();
example.setEmployed(true);
example.setLastName("Smith");
example.setDob(LocalDate.of(1977, Month.JANUARY, 1));
List<Person> foundPersons = personRepository.findByExample(example);
Run Code Online (Sandbox Code Playgroud) 这是一个简单的值bean,使用Spring的新版本(3.0版本) @DateTimeFormat注释(根据我的理解PropertyEditor,根据此SO问题替换了3.0之前的自定义需求):
import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
public class Widget {
private String name;
@DateTimeFormat(pattern = "MM/dd/yyyy")
private LocalDate created;
// getters/setters excluded
}
Run Code Online (Sandbox Code Playgroud)
将表单提交中的值与此窗口小部件结合使用时,日期格式可以正常运行.也就是说,只有MM/dd/yyyy格式中的日期字符串才能成功转换为实际LocalDate对象.太棒了,我们就在那里.
然而,我也想能够还显示所创建的LocalDate在同一个JSP视图属性MM/dd/yyyy格式使用JSP EL像这样(假设我的弹簧控制器添加小窗口属性的模型):
${widget.created}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这只会显示默认toString格式LocalDate(yyyy-MM-dd格式).我知道如果我使用spring的表单标签,日期会根据需要显示:
<form:form commandName="widget">
Widget created: <form:input path="created"/>
</form:form>
Run Code Online (Sandbox Code Playgroud)
但我想在不使用spring form标签的情况下显示格式化的日期字符串.甚至是JSTL的fmt:formatDate标签.
来自Struts2,HttpServletRequest包含在一个StrutsRequestWrapper启用这样的EL表达式实际上询问OGNL值栈.所以我想知道spring是否提供类似的东西以允许转换器执行?
编辑
我也意识到,当使用spring的eval标签时,日期将根据@DateTimeFormat注释中定义的模式显示:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<spring:eval expression="widget.created"/>
Run Code Online (Sandbox Code Playgroud)
有趣的是,使用自定义当PropertyEditor格式化日期,该标签不会调用该PropertyEditor …
如何允许CDI将资源注入到宁静的Web服务资源中?我使用焊接2(cdi),泽西(jaxrs)和灰熊(网络服务器)在标准java上运行.这是我简单的网络资源:
import training.student.StudentRepository;
import javax.inject.Inject;
import javax.ws.rs.*;
@Path("student")
public class StudentWebResource {
@Inject
private StudentRepository studentRepository;
@GET
@Path("count")
@Produces(MediaType.TEXT_PLAIN)
public Integer getCount() {
return studentRepository.studentCount();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我如何焊接启动我的简单Web服务器:
public class Main {
public static void main(String[] args) throws Exception {
startCdiApplication();
}
public static void startCdiApplication() throws Exception {
Weld weld = new Weld();
try {
WeldContainer container = weld.initialize();
Application application = container.instance().select(WebServer.class).get();
application.run();
}
finally {
weld.shutdown();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我怀疑的代码需要修改,以通知球衣使用焊接CDI注入分辨率:
...
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.jackson.JacksonFeature; …Run Code Online (Sandbox Code Playgroud) 我刚刚下载了用于Java SE 7的Oracle服务器JRE(链接)我下载的文件是server-jre-7u45-linux-x64.tar.gz.当我解压缩这个文件时,我很惊讶地发现创建了一个名为jdk1.7.0_45的目录,其中包含完整的Java JDK.不是我对JRE安装的期望.这里发生了什么?
如何使用@Value注释注入字符串值列表.我正在使用Spring 4.1.2.
我试过了:
@Value(value = "top, person, organizationalPerson, user")
private List<String> userObjectClasses
Run Code Online (Sandbox Code Playgroud)
然后根据内联列表的spring el文档:
@Value(value = "{top, person, organizationalPerson, user}")
private List<String> userObjectClasses
Run Code Online (Sandbox Code Playgroud)
这些尝试仅注入作为列表中唯一元素给出的值的字符串文字.
编辑
在这种情况下,我希望能够简单地对值进行硬编码,而不是从属性文件中读取.这种方法看起来有点不如:
private List<String> userObjectClasses = Arrays.asList(new String[] {"top", "person", "organizationalPerson", "user"});
Run Code Online (Sandbox Code Playgroud)
在过去,我使用spring的XML配置来连接bean,在这种情况下我可以做(假设bean有一个userObjectClasses属性的公共setter ):
<property value="userObjectClass">
<list>
<value>top</value>
<value>person</value>
<value>organizationalPerson</value>
<value>user</value>
</list>
</property>
Run Code Online (Sandbox Code Playgroud)
使用基于注释的配置时是否有类似的功能?
我正在使用Grails 2.3.7.我有一个简单的Person域对象:
class Person {
String name
static constraints = {}
}
Run Code Online (Sandbox Code Playgroud)
和控制器:
@Transactional(readOnly = true)
class PersonController {
def index() {
render view:'index', model:[personList:Person.list()]
}
def show(Long id) {
def person = Person.get(id)
render view:'show', model:[person:person]
}
...
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试为控制器编写一个单元测试来练习该show方法,但我不确定如何配置测试以确保静态调用Person.get(id)返回一个值.
这是我的(失败)尝试:
import grails.test.mixin.*
import spock.lang.*
@TestFor(PersonController)
@Mock(Person)
class PersonControllerSpec extends Specification {
void "Test show action loads Person by id and includes that person in the model rendered"() {
setup:
def personMockControl = mockFor(Person)
personMockControl.demand.static.get() …Run Code Online (Sandbox Code Playgroud) 我在这里提出同样的问题,因为其中提供的答案不能解决我的问题。
我在 Spring MVC Web 应用程序中使用 Spring 4.1.3。我有一个包含该字段的 JPA 实体 bean:
@DateTimeFormat(pattern = "${date.format}")
private LocalDate certifiedOn;
Run Code Online (Sandbox Code Playgroud)
我希望基于属性文件中的键注入模式。 从 3.0.3 开始,这应该在 Spring 中工作,但是控制器中的绑定失败,因为Pattern includes reserved character '{'.
我知道我正在成功读取我的属性文件,因为应用程序中正在使用其他属性。这是我通过 javaConfig 进行设置的方法:
@Configuration
@ComponentScan(basePackages = "com")
@PropertySource("classpath:spring.properties")
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
...
}
Run Code Online (Sandbox Code Playgroud)
在类路径的根目录下有spring.properties文件:
date.format = yyyy-MM-dd
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么会阻止它工作?
我正在使用tomcat 8.0.9(servlet 3.1,jsp 2.3,el 3.0)并尝试从jsp页面访问静态属性,如下所示:
${Boolean.TRUE}
Run Code Online (Sandbox Code Playgroud)
没有错误,但渲染结果中没有输出.我究竟做错了什么?
编辑
这个问题的答案(标记为重复问题)声称,自从EL 3.0(JSR-341,Java EE 7的一部分)以来,可以引用所有java.lang.*类的常量,因为它们是隐式导入的,并且可以像所以
${Boolean.TRUE}
Run Code Online (Sandbox Code Playgroud)
这个答案对我不起作用,至少不适用于tomcat 8.
编辑2
来自Oracle的JEE7教程(9.3.1.2引用对象属性或集合元素)
您可以使用语法classname.field引用静态字段或方法,如下例所示:
Boolean.FALSE
classname是没有包名的类的名称.默认情况下,将导入所有java.lang包.您可以根据需要导入其他包,类和静态字段.
在我投入精力构建一个实用程序来询问并ObjectMapper通过以下方法输出其配置之前:
objectMapper.getRegisteredModuleIds();
objectMapper.getDeserializationConfig().hasDeserializationFeatures(...);
objectMapper.getSerializationConfig().hasSerializationFeatures(...);
Run Code Online (Sandbox Code Playgroud)
我想知道是否已经有某种方法(在杰克逊本身或现有的实用程序中)来输出给定的配置ObjectMapper?例如,如果ObjectMapper设置如下:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Run Code Online (Sandbox Code Playgroud)
我想在事后检查ObjectMapper并确切地了解它是如何配置的。
java ×10
spring ×5
spring-mvc ×3
jsp ×2
cdi ×1
dropwizard ×1
el ×1
grails ×1
grizzly ×1
jackson ×1
jax-rs ×1
jersey ×1
jspell ×1
jvm-hotspot ×1
mocking ×1
spring-4 ×1
spring-boot ×1
spring-data ×1
tomcat ×1
tomcat8 ×1
unit-testing ×1
war ×1