Typically resource bundles are loaded and used within a JSP using JSTL and fmt, but this requires to always use the syntax <fmt:message key=""/> to access the value.
When the text to be localized looks like
<a href="url" title="message"> it is awkward (though valid to write):
<a href="url" title="<fmt:message key="key"/>">
and plain awkward to use the scoped syntax
<fmt:message key="key" var="var">
<a href="url" title="${var}">
</fmt:message>
Is there a simpler way to do this? I am looking for something like just
<a href="url" title="${messages.key}">
Yes, the below is a copy of my answer at Is there a shorthand for <fmt:message key="key" />? as mentioned in Bozho's comment on your question. But since that question is actually Spring-targeted, my answer wasn't fully applicable there. Your question is however not Spring-targeted, but just plain JSP/Servlet targeted and can therefore not be closed as exact dupe. So I think the answer is better at its place here:
You can create a class which extendsResourceBundle, manage the loading yourself with help of a Filter (based on request path?) and store it in the session scope. The ResourceBundle is accessible the usual JSP EL way. You can access it as if it's a Map. The handleGetObject() method will be invoked on every access.
Here's a kickoff example:
package com.example.i18n;
import java.util.Enumeration;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
public class Text extends ResourceBundle {
private static final String TEXT_ATTRIBUTE_NAME = "text";
private static final String TEXT_BASE_NAME = "com.example.i18n.text";
private Text(Locale locale) {
setLocale(locale);
}
public static void setFor(HttpServletRequest request) {
if (request.getSession().getAttribute(TEXT_ATTRIBUTE_NAME) == null) {
request.getSession().setAttribute(TEXT_ATTRIBUTE_NAME, new Text(request.getLocale()));
}
}
public static Text getCurrentInstance(HttpServletRequest request) {
return (Text) request.getSession().getAttribute(TEXT_ATTRIBUTE_NAME);
}
public void setLocale(Locale locale) {
if (parent == null || !parent.getLocale().equals(locale)) {
setParent(getBundle(TEXT_BASE_NAME, locale));
}
}
#Override
public Enumeration<String> getKeys() {
return parent.getKeys();
}
#Override
protected Object handleGetObject(String key) {
return parent.getObject(key);
}
}
(note the TEXT_BASE_NAME constant should refer to name of the resource bundle files, the above example assumes that you've text.properties, text_en.properties, etc in the com.example.i18n package)
The Filter:
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Text.setFor((HttpServletRequest) request);
chain.doFilter(request, response);
}
JSP:
<p>${text['home.paragraph']}</p>
If you want to change the locale from inside some servlet or filter:
Text.getCurrentInstance(request).setLocale(newLocale);
Related/interesting-to-know:
Overriding ResourceBundle#Control to read files using UTF-8
List all available ResourceBundle files
Iterating through multiple properties from ResourceBundle
How to internationalize a Java web application?
To do what you want you may need to create and register your own ELResolver. Take a look at this answer - Alternative to using c:out to prevent XSS.
So you might reserve a prefix such as MESSAGES and translate that into a ResourceBundle lookup.
i.e. ${MESSAGES.key} gets processed by your ELResolver as bundle.getString(key).
Related
When I try to invoke parserAction() method inside an another servlet class I'm getting a blank array. I cant print the nouns inside my servlet. But inside this class with the MAIN METHOD noun array is printing correctly. What is the reason for this ?
package com.books.servlet;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;
import com.sun.corba.se.impl.orb.ParserAction;
import opennlp.tools.cmdline.parser.ParserTool;
import opennlp.tools.parser.Parse;
import opennlp.tools.parser.Parser;
import opennlp.tools.parser.ParserFactory;
import opennlp.tools.parser.ParserModel;
public class ParserTest {
public static Set<String> nounPhrases = new HashSet<>();
public String line = "I need the java book";
public void getNounPhrases(Parse p) {
if (p.getType().equals("NN") || p.getType().equals("NNS") || p.getType().equals("NNP")
|| p.getType().equals("NNPS")) {
nounPhrases.add(p.getCoveredText());
// System.out.println(p.getCoveredText());
}
for (Parse child : p.getChildren()) {
getNounPhrases(child);
}
}
public void parserAction() throws Exception {
InputStream is = new FileInputStream("en-parser-chunking.bin");
ParserModel model = new ParserModel(is);
Parser parser = ParserFactory.create(model);
Parse topParses[] = ParserTool.parseLine(line, parser, 1);
for (Parse p : topParses) {
// p.show();
getNounPhrases(p);
}
}
public static void main(String[] args) throws Exception {
new ParserTest().parserAction();
System.out.println("List of Noun Parse : "+nounPhrases);
}
}
Below is my sample servlet class. It shows me a blank array with []
public class test extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
.......
.......
.......
ParserTest pt = new ParserTest();
pt.parserAction();
System.out.println("List of Noun Parse : "+pt.nounPhrases);
System.out.println("List of Noun Parse : "+ParserTest.nounPhrases);
}
}
Here I need to extract nouns without executing a main method. Since I'm developing a web application. I need to show these extracted nouns inside one of my servlet class.
You need to write what you want in the response, for example by doing:
response.getWriter().println("Whatever you want to write in the response");
But first I would suggest to read some good Java books as your code is not very good, also servlets are an old way of doing Java web application, nowadays people use other technologies, like templates using JSP or JSF, JAX-RS for REST applications, JAX-WS for SOAP applications, ...
I'd like to make one text for multiple html files, something like greating. Let's say greating is:
"Hello, if you have any questions please conatact me."
What I want is to recall that text on every html page. And later if I change it, the change would appear on all the html pages.
I am weak on java, but I think I need to create some javascript and recall the text with div class function, like the facebook button is made.
P.S. Facebook button recall:
<div class="fb-like" data-href="https://developers.facebook.com/docs/plugins/" data- layout="standard" data-action="like" data-show-faces="true" data-share="true">
with javascript you can change the content of a tag with html() function, or you could include the resource, i guess it depends on the technology being used
In the simplest form, you can create a function in your javascript master copy and make a document.write call. You would need to call that script file on every page.
function greetingMessage() {
document.write('your message);
};
Then
call greetingMessage();
you can also put the javascript in a master file and then have the div in each HTML page:
function greetingMessage(){
document.getElementById('Message').innerHTML = 'Your Message';
};
HTML:
<body onload="greetingMessage();">
<div id="Message" style="color:red;"></div>
If you are using JSP's or Servlets you can have a resource/properties file that contains many Strings being used throughout your application. The properties file would contain key=value pairs. You could then simply reference a particular key in the properties file, for instance:
greeting=Hello, if you have any questions please contact me
The key is "greeting", the value is "Hello, if you have any questions please contact me"
To read in the properties file you would use the Properties class like so:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MyWebPage extends HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse res)
{
PrintWriter out = response.getWriter();
response.setContentType("text/html");
out.print("<html><head></head><body><div class=\"someclass\">" +
getGreeting() + "</div>"
"</body></html>"
);
}
public String getGreeting()
{
String greeting = "";
try{
Properties prop = new Properties();
InputStream input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
greeting = prop.getProperty("greeting");
input.close();
}
catch(IOException ioe){ioe.printStackTrace();}
finally{
if (input != null)
{
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return greeting;
}
}
The same sort of thing can be effectively used in Java Server Pages. Hope this helps.
I need to make w WS call to handle HEAD request by myself, anyway it always get's response AFTER redirection (so finally I get always 200 status instead of ie. 301)
In documentation it's written that I should set ws.followRedirects=false in my application.conf, anyway it doesn't seem to work. I can see that Scala version is trying read this config, however I have a Java controller. Also can't switch to 2.1 now, where as I can see there is special setter for the issue.
Is there ANY workaround ?
You can call Scala from Java. The method wsHead encapsulates the Scala code and delivers only Objects from the Java Play API. Migrated to Play 2.1.0 you can refactor that method.
package controllers;
import play.api.libs.ws.Response;
import play.api.libs.ws.WS$;
import play.libs.F;
import play.libs.WS;
import play.mvc.*;
public class Application extends Controller {
public static Result index() {
final String url = "http://localhost:80";
final F.Promise<WS.Response> responsePromise = wsHead(url);
return async(responsePromise.map(new F.Function<WS.Response, Result>() {
#Override
public Result apply(WS.Response response) throws Throwable {
return ok("got status: " + response.getStatus());
}
}));
}
private static F.Promise<WS.Response> wsHead(String url) {
return new F.Promise(WS$.MODULE$.url(url).head()).map(new F.Function<Response, WS.Response>() {
#Override
public WS.Response apply(Response o) throws Throwable {
return new WS.Response(o.getAHCResponse());
}
});
}
}
You still need to add ws.followRedirects=false in your application.conf.
I've spend some time to add smack.providers in the android device, which is picked up by my application just fine. I've added the default iqProviders and extensionProviders, but I've also added my custom extensionProvider, which is the following:
<extensionProvider>
<elementName>players</elementName>
<namespace>boxer:players</namespace>
<className>company.games.boxer.PlayerListProvider</className>
</extensionProvider>
Let me also introduce the PlayerListProvider class, which is currently there just to see if it will get called (which it doesn't) - I'll implement it fully when I'll know it gets called, therefore at least that part of functionality works:
import java.util.List;
import java.util.Map;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smackx.provider.EmbeddedExtensionProvider;
import android.util.Log;
#SuppressWarnings("deprecation")
class PlayerListProvider extends EmbeddedExtensionProvider {
protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String,String> attributeMap, List<? extends PacketExtension> content) {
Log.w("***** AAAAAAAAAAAAAAAAAAAA *******", "0");
return new XMLPlayerList();
}
}
class XMLPlayerList implements PacketExtension {
public String getElementName() {
return "aaaaa";
}
public String getNamespace() {
return "aaaaa";
}
public String toXML() {
return "aaaaa";
}
}
And I'm getting the following message when I run the client android app:
<message to="eee#localhost" type="chat" id="9" from="admin#localhost">
<body>
<players xmlns="boxer:players" command="playerlist">
<player>test1</player>
<player>test2</player>
</players>
</body>
<thread>3P0i00</thread>
</message>
My question now is, why isn't the PlayerListProvider (EmbeddedExtensionProvider) called upon receiving the message. The message contains the tag and has the namespace of boxer:player, as I specified in smack.providers.
Any thoughts?
After reading about similar issues here on SO, I came across this question/answer and this blog post about another way (part 1) (part 2) to implement the custom message sending/receiving.
Have you considered using PacketExtensionProvider instead of EmbeddedExtensionProvider?
It's explained in more detail here, if you are interested in trying it out in place of the EmbeddedExtensionProvider. It might not be exactly what you are looking for... (it appears like it takes more of a manual-parsing approach,) but it might get your PlayerListProvider class recognized (via extending the PEPEvent class.)
out.println("<tr><td><FORM ENCTYPE='multipart/form-data'"+
"method='POST' action='ProcessUpload' ></td>"+
"<td><INPUT TYPE='file' NAME='mptest'></td>"+
"<td><INPUT TYPE='submit' VALUE='upload'></td>"+
"</FORM></tr>");
This codes can help me upload file but the problem is after I click upload, I cant save the uploaded file in particular directory.Anyone can give some suggestion?
The code above simply outputs the HTML for an upload button. It does not do anything with any upload requests that form might start.
May I ask why you don't want to use Apache Commons FileUpload? To not use it will mean that you will need to implement RFC 1867. A lot of time and effort wasted when an implementation already exists.
You have to write another servlet (or some CGI, jsp ...etc.) to retrieve the file from the request and save it to wherever you like:
http://www.frontiernet.net/~Imaging/FileUploadServlet.html
Apache Commons FileUpload is the way to go as others suggested. If you don't want use that for any reason, you can also look at this class,
http://metatemplate.googlecode.com/svn/trunk/metatemplate/java-app-framework/tomcat-adapter/src/com/oreilly/servlet/MultipartRequest.java
This is not as robust as FileUpload but it works fine for simple file upload.
If you want to use Multipart request you need to write your processUpload servlet to handle this eg:
private String fileSavePath;
public void init(){
fileSavePath = getServletContext().getRealPath("/") + "data";
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
MultipartRequest mpr = new MultipartRequest(request, fileSavePath);
}
And I really wouldn't output pure html from a servlet as in your question - try dispatching to a jsp - even better if nothing else is required just use plain html.
The COS libary http://servlets.com/cos/ (not apache)
I second mlk's suggestion and think reading the Users Guide to Commons FileUpload will help you get started. It will handle receiving the file, but you still have to tell it "where" to store it. From your description, sounds like you want the user to choose "where" to store the file. You will have to write this portion yourself.
I hacked together a quick lister in a servlet. All the other comments are correct. Not a good idea to write html in a servlet, but this sounds like a good learning experience.
package somepackage;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DirectoryChooserServlet extends HttpServlet {
public DirectoryChooserServlet() {
super();
}
#Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
Writer w = response.getWriter();
w.write("<html><body>");
String action = request.getParameter("action");
String directory = request.getParameter("directory");
String startDirectory = "/private";
if ("list".equals(action)) {
startDirectory = directory;
}
File dir = new File(startDirectory);
if (dir != null) {
w.write("..<br/>");
for(File f: dir.listFiles()) {
if(f.isDirectory()) {
w.write("" + f.getName() + "<br/>");
}
}
}
w.write("</body></html>");
}
}