Russell Bateman May 2018
What do you do to cause Maven to build a WAR file? Add this to pom.xml:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.2.0</version> <configuration> <webResources> <resource> <!-- this is relative to the pom.xml directory --> <directory>web</directory> </resource> </webResources> </configuration> </plugin> </plugins> </build>
The <directory> specified above assumes the following structure in your project:
~/dev/hello-restlet $ tree . ├── hello-restlet.iml ├── pom.xml ├── src │ └── ... └── web └── WEB-INF └── web.xml
I downloaded IntelliJ IDEA Ultimate (here at work too) and then did Install and Configure Tomcat IntelliJ IDEA which is a year old, has no sound and is full of misleading mousing. Here I am reducing that experience to a set of steps. It did work, however, and that puts me hugely up over the experience I had with Eclipse WTP back in 2008 when I really started in earnest trying to learn to do web programming with Eclipse.
Hello viewer Please Subscribe Thanks For Waching...
This is working, so I'm going to have to spring the $150 for this IDE now.
These are practical and up-to-date instructions based on Sam Jesso's 2014 Starting out with Jersey & Apache Tomcat using IntelliJ. Here are the steps, illustrations and elaborations I followed:
<?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.example.jersey</groupId> <artifactId>hello-rest</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-bundle</artifactId> <version>1.19.1</version> </dependency> </dependencies> </project>
package com.example.jersey; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path( "/hello" ) public class HelloWorld { @GET @Produces( MediaType.TEXT_PLAIN ) public String getMessage() { return "Hello world!"; } }
It is imperative that you pay close attention to the URL under Open browser below: unlike how Eclipse deploys and works, IDEA must have the URL to this degree of specificity in order to work. You will see a new tab appear in your browser with this URL and little else. If you do not have a complete URL, depending on the options of your servlet, you likely will get HTTP 404 and nothing will work.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>Example API</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.example.jersey</param-value> </init-param> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Example API</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
* Optionally, you can scrape these, paste them into a simple editor like vim, gvim or gedit, then copy them from there into your new class.
Next up should be a tutorial on how to endow the restlet above with an index.jsp (that's meaningful and not the template one that appeared above as the result of adding frameworks) that does something.
If developing on two hosts, or if collaborating with others, you will not be maintaining .idea/workspace.xml under version control (for all sorts of reasons). Therefore, the step on creating a run/debug configuration will have to be done in every IDEA instance you run. .idea/workspace.xml is where this is kept because, in this case, it's a file-system dependent operation (i.e.: where your copy of Tomcat lives).
This is an interpretation of Part 1.1: Java EE Webapplication with servlet and JSP page.
<%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Web App Tutorial Page</title> </head> <body> <h1> Hello World </h1> <p> Body text. This is my first webapp JSP page. </p> </body> </html>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> (empty) </web-app>
<%@ page import="java.util.Date" %> <%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Web App Tutorial Page</title> </head> <body> <h1> Hello World </h1> <p> Body text. This is my first webapp JSP page. </p> <% Date date = new Date(); out.print( "<h3>" + date.toString() + "</h3>" ); %> </body> </html>
<%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Login Page</title> </head> <body> <h1> Welcome, please log in: </h1> <form action="/login" method="POST"> Name: <input type="text" name="username" width="30" /><br /> Password: <input type="password" name="password" width="10" /><br /> <input type="submit" value="login" /> </form> </body> </html>
package webapp; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet( name = "Login" ) public class Login extends HttpServlet { protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { } protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> Login webapp.Login Login /login </web-app>
protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String username = request.getParameter( "username" ); String password = request.getParameter( "password" ); PrintWriter out = response.getWriter(); out.println( "Username: " + username ); out.println( "Password: " + password ); }
protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String username = request.getParameter( "username" ); String password = request.getParameter( "password" ); PrintWriter out = response.getWriter(); out.println( "From POST'd form:" ); out.println( "Username: " + username ); out.println( "Password: " + password ); }
<%-- Created by IntelliJ IDEA. User: russ Date: 5/7/18 Time: 3:09 PM To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> Welcome </title> </head> <body> <h1> Welcome </h1> <p> Dear: ${username}, your password is ${password}. <!-- (${} is called "expression language") --> </p> </body> </html>
package webapp; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet( name = "Login" ) public class Login extends HttpServlet { private static final String QPARM_USERNAME = "username"; private static final String QPARM_PASSWORD = "password"; private static final String JSP_USERNAME = "username"; private static final String JSP_PASSWORD = "password"; protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { request.setAttribute( JSP_USERNAME, request.getParameter( QPARM_USERNAME ) ); request.setAttribute( JSP_PASSWORD, request.getParameter( QPARM_PASSWORD ) ); request.getRequestDispatcher( "/welcome.jsp" ).forward( request, response ); } protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws IOException { String username = request.getParameter( QPARM_USERNAME ); String password = request.getParameter( QPARM_PASSWORD ); PrintWriter out = response.getWriter(); out.println( "Username: " + username ); out.println( "Password: " + password ); } }
package pojo; public class User { private String username; private String password; public User( final String username, final String password ) { this.username = username; this.password = password; } public boolean isValidUsername() { return username.equals( "russ" ); } public boolean isValidPassword() { return password.equals( "snagglepuss" ); } }
private static final String QPARM_USERNAME = "username"; private static final String QPARM_PASSWORD = "password"; private static final String JSP_USERNAME = "username"; private static final String JSP_PASSWORD = "password"; private static final String INVALID_USERNAME = "username is unknown"; private static final String INVALID_PASSWORD = "password was wrong"; protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String username = request.getParameter( QPARM_USERNAME ); String password = request.getParameter( QPARM_PASSWORD ); User user = new User( username, password ); String errors = ""; if( !user.isValidUsername() ) errors += " " + INVALID_USERNAME + " (" + username + ")<br />"; else if( !user.isValidPassword() ) errors += " " + INVALID_PASSWORD + " (" + password + ")<br />"; if( errors.length() < 1 ) { request.setAttribute( JSP_USERNAME, request.getParameter( QPARM_USERNAME ) ); request.setAttribute( JSP_PASSWORD, request.getParameter( QPARM_PASSWORD ) ); request.getRequestDispatcher( "/welcome.jsp" ).forward( request, response ); } else { request.setAttribute( "error_message", "Invalid login:<br />" + errors + "Please try again." ); request.getRequestDispatcher( "/login.jsp" ).forward( request, response ); } }
<%-- Created by IntelliJ IDEA. User: russ Date: 5/4/18 Time: 10:25 AM To change this template use File | Settings | File Templates. Note: because this file is fetched implicitly because under the web subdirectory, even without being named in a welcome-file-list element. --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Login Page</title> </head> <body> <h1> Welcome, please log in: </h1> <form action="/login" method="POST"> Name: <input type="text" name="username" width="30" /><br /> Password: <input type="password" name="password" width="10" /><br /> <input type="submit" value="Log in" /> </form> <p> <span style="color: red"> ${error_message} </span> </p> </body> </html>
What if you've got a project that you did not originally create with adequate resources and framework support?
If you erase the .idea subdirectory, then create a new project in IDEA giving it the name of the project you wish to change, you can accomplish the same thing without creating a whole new project only to copy all your code and other resources into it.* For example:
* which is certainly a simpler if more tedious option.