问题
In a project that I got assigned which is using Struts2 I need to do the following things, but I'm new to using Struts2.
- Move text from titles and most common / repeating texts to a
.properties
file. - Change URLs from images to make the system parameterized, so they should be in the same
.properties
file as well.
I've been able to change some of the titles, first linking Struts2 with my .properties
file, following this answer.
Content.properties
login.logo=/resources/media/login.png
login.title=Login
Now, my JSP file is been used only as a HTML file and this is how it looks like:
login.jsp
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<%@taglib prefix="sj" uri="/struts-jquery-tags"%>
<%@taglib prefix="sjg" uri="/struts-jquery-grid-tags"%>
<%@taglib prefix="sb" uri="/struts-bootstrap-tags"%>
<%@taglib prefix="decorator" uri="sitemesh-decorator"%>
<%
response.setHeader("Cache-Control", "no-cache"); //HTTP 1.1
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setDateHeader("Expires", -1); //evita o caching no servidor proxy
%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta charset="UTF-8" />
<title><s:text name="login.title" /></title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="shortcut icon" href='<s:url value="/resources/media/favicon_seg.ico"/>' />
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<sj:head locale="es" jqueryui="true" jquerytheme="ui-lightness" compressed="true" defaultIndicator="ajax_loading" />
<sb:head />
<link rel="stylesheet" href='<s:url value="/resources/css/login.css"/>' />
</head>
<body>
<div class="panel-footer ">
<img height="40" src="<s:url value="/resources/media/login.png"/>" class="pagelogo" alt="Logo" /> My Company
</div>
</body>
</html>
However if I wanted to use the properties file changing this part in the file above like this:
<img height="40" src="<s:url value="${login.logo}"/>" class="pagelogo" alt="Logo" /> My Company
Sometimes I get the page displayed correctly, sometimes not, but after refreshing it (F5) it again displays or not. When not displayed I get the following error:
SEVERE: Servlet.service() for servlet [jsp] threw exception
org.apache.jasper.JasperException: /WEB-INF/content/login.jsp (line: [87], column: [28]) According to TLD or attribute directive in tag file, attribute [value] does not accept any expressions
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:42)
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:291)
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:114)
at org.apache.jasper.compiler.Validator$ValidateVisitor.checkXmlAttributes(Validator.java:1241)
at org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:879)
at org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1545)
at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2392)
at org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2444)
at org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2450)
at org.apache.jasper.compiler.Node$Root.accept(Node.java:471)
at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2392)
at org.apache.jasper.compiler.Validator.validateExDirectives(Validator.java:1853)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:221)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:374)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:351)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:335)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:601)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:368)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:59)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:590)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:524)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:895)
at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:648)
at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:132)
at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:372)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:276)
at org.apache.struts2.interceptor.CookieProviderInterceptor.intercept(CookieProviderInterceptor.java:75)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.CookieInterceptor.intercept(CookieInterceptor.java:258)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.CookieInterceptor.intercept(CookieInterceptor.java:258)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:76)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:253)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.components.ActionComponent.executeAction(ActionComponent.java:288)
at org.apache.struts2.components.ActionComponent.end(ActionComponent.java:172)
at org.apache.struts2.views.jsp.ComponentTagSupport.doEndTag(ComponentTagSupport.java:42)
at org.apache.jsp.index_jsp._jspx_meth_s_005faction_005f0(index_jsp.java:168)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:127)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
at org.apache.catalina.core.ApplicationFilterC2017-12-11 11:04:52,566 ERROR (org.apache.struts2.components.ActionComponent) - Could not execute action: //login
hain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
What could be the correct way to get the path of the image and get it displayed in the JSP without getting the error above sometimes?
I found some questions related to this error, but they're using JSTL and I'm not.
I found another post while writing this question: JSP2 expression in Struts2 form input in which they recommend using OGNL and from what I've read is the form:
<s:url ...>
Correct me if I'm wrong, since these are new concepts to me
Here's the post extract
By default you cannot pass a JSP EL expression to a Struts2 tag. This is done for security purposes. If you wanted to, you could make a copy of struts-tags.tld and set to true for all of the tags. However, you should be aware of the security vulnerability involved in allowing tags to accept both JSP EL and OGNL expressions.
JSP EL is evaluated prior to invoking the tag handler, OGNL is evaluated afterwards (inside the tag). As such, if ${retPage} evaluated to an OGNL expression, then the tag may wind up doing something you didn't expect.
So, in this case could there be any workaround for doing what I want to do (get the image url from my properties file and displaying it either way using OGNL or EL?
Edit:
I've also tried this answer's solution: https://stackoverflow.com/a/21673153/2180785
Which suggests changing s:url
to c:url
in which case it doesn't produce a blank page (as the question mentions it and is what happens with mine as well when reloading the page), but this leads to a broken-image
image along with some html as shown below:
If needed I can provide any extra information required since I thought this was the needed one but as I said, I'm new to those technologies and thus don't know if anything else is required for this question to be complete or clear enough to answer.
回答1:
I kept on looking for an answer to my question and found the following question: How to create dynamic images with struts2?
Which contained the answer to my question in the accepted answer:
There is another simple way by using
<img src=<s:text name="genTP" /> />
. But I think is quite strange.
Which in my case translated to this:
<img height="40" src="<s:text name="login.logo"/>" class="pagelogo" alt="Logo" /> Login
And having my content.properties
file changed this way for the image path:
login.logo=/oneFolderBefore/resources/media/login.png
login.title=Login
With that, I was able to display my image from my properties file correctly, avoiding the error mentioned above.
来源:https://stackoverflow.com/questions/47758121/struts2-display-image-get-image-url-from-a-properties-file