We have an application developed in Spring MVC and deployed on a Jetty 9 Standalone (JDK 1.8) and served in principle without Apache / Nginx.
The application makes, internally, requests to obtain external xml and xsd files to make a series of validations.
We would need to be able to intercept the calls, especially for the response as we need to be able to modify the xmls and xsds (to remove a number of characters).
The challenge is that we can NOT modify the application. That is we cannot add something to the source code and recompile.
The first strategy has been to include a jar with a Filter / ServletFilter but only to log the requests, so that we could check if the GET calls that we suppose the controller makes to the xml / xsd appear.
Filter code
package com.htmlfilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class HtmlFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("HtmlFilter: init method");
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("HtmlFilter: doFilter method");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String path = httpServletRequest.getRequestURI().substring(httpServletRequest.getContextPath().length());
System.out.println(path);
chain.doFilter(request, response);
}
#Override
public void destroy() {
System.out.println("HtmlFilter: destroy method");
}
}
ServletFilter code
package com.htmlfilter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HtmlServletFilter extends HttpServlet {
public void init() throws ServletException {
System.out.println("HtmlServletFilter: init");
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
System.out.println("HtmlServletFilter: doGet");
String path = request.getRequestURI();
System.out.println(path);
response.getWriter().println("Hello This is GET
Response.");
}
}
web.xml
<filter>
<filter-name>HtmlFilter</filter-name>
<filter-class>com.htmlfilter.HtmlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HtmlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>HtmlServletFilter</servlet-name>
<servlet-class>com.htmlfilter.HtmlServletFilter</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HtmlServletFilter</servlet-name>
<url-pattern>*.xsd</url-pattern>
</servlet-mapping>
Related
PrintNamesServlet.java:
This servlet prints the entered name of the user
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 = "PrintNamesServlet")
public class PrintNamesServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Ram Dhakal");
}
}
CounterServlet.java:
Counts the number of hits or visit in the page
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 = "CounterServlet") public class CounterServlet
extends HttpServlet {
int totalHits;
public void init() throws ServletException{
totalHits = 0;
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print("Total visit count: " + totalHits++);
} public void destroy(){
}
}
web.xml:
<?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_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>PrintNamesServlet</servlet-name>
<servlet-class>PrintNamesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PrintNamesServlet</servlet-name>
<url-pattern>/PrintNamesServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CounterServlet</servlet-name>
<servlet-class>CounterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CounterServlet</servlet-name>
<url-pattern>/CounterServlet</url-pattern>
</servlet-mapping>
</web-app>
I am getting error:
No webpage was found for the web address: http://localhost:8080/
As, I am trying to run the servlet for the first time, I am not getting what is wrong with my code. I typed http://localhost:8080/PrintNamesServlet in the url.
You have used Servlet 3.0 specification
Lets takes look at it
In Servlet 3.0, servlet metadata can be specified using #WebServlet
#WebServlet(name="mytest",
urlPatterns={"/myurl"})
public class TestServlet extends javax.servlet.http.HttpServlet {
....
}
In this way the servlet is accessed by using the url pattern specified in the annotation.
##WebServlet(name="mytest",urlPatterns={"/myurl"})
according to that servlet is acceseed using
http://localhost:8080/myurl
In you case you have only specified name you have to specify urlPatterns also, so you can able to call you servlet properly.
#WebServlet(name = "CounterServlet",urlPatterns={"/CounterServlet"}) public class CounterServlet extends HttpServlet {}
And you do not need to use web.xml file.
When you use annotations like this #WebServlet(name = "PrintNamesServlet") the web.xml mapping is not used.
You have to either remove these annotations or add urlMapping attribute to them.
Appreciate any help.
I'm facing the problem with the CORS on my newly deployed Tomcat 8.0.30. I keep getting the error below. I am using 127.0.0.1 as the API server address and 192.168.1.100 is the address of my HTTP server.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '_http://192.168.1.100:8999' is therefore not allowed access. The response had HTTP status code 403.
Read through whole Tomcat documentation, added the cors filter under the tomcat web.xml, as well as the project web.xml, but nothing magic happens here, still getting the same error. Tried both minimal and advanced with init-param, same error.
I am using Spring 4 as my rest api framework. Any more configurations need to be done on the project coding part?
Here are the steps I've done so far:
add cors filter under web.xml, mininal config according to documentation, not working
add cors filter under web.xml, full config, not working as well.
tried to use cors filter from http://software.dzhuvinov.com/cors-filter.html, still not working
Any suggestions?
Add the web.xml configuration
I've tried to change cors.allowed.origins to *, to 127.0.0.1,192.168.1.100, all not working,
remove credentials and maxage
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://192.168.1.100</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Suggested by Vishal, changing tomcat version from 8.0 to 8.5, still same issue
XMLHttpRequest cannot load http://127.0.0.1:8080/leyutech-framework-gurunwanfeng/api/ad/getAdInfoByAdType.html?adType=0. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.168.1.100:8080' is therefore not allowed access. The response had HTTP status code 403.
I've used the custom filter to accomplish this issue, I have no idea why offical tomcat cors filter is not working in my case, Any one can suggest the logic behind this, I am willing to try this out.
Original Post from Tobia
The code is modified from the link above.
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
public void destroy() {
// TODO Auto-generated method stub
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
web.xml configuration under current project
<filter>
<filter-name>SimpleCORSFilter</filter-name>
<filter-class>com.example.util.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SimpleCORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I encountered this problem once and I developed a custom handler for a Jetty Web application.
Maybe it can help you.
CORSHandler.hava
import java.io.IOException;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.Request;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
public class CORSHandler extends HandlerWrapper {
public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
public CORSHandler() {
super();
}
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
// Allow Cross-site HTTP requests (CORS)
response.addHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
// Accept Content-Type in header
response.addHeader(ACCESS_CONTROL_ALLOW_HEADERS, "content-type");
// Accept GET, POST, PUT and DELETE methods
response.addHeader(ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,PUT,DELETE");
if (_handler!=null && isStarted())
{
_handler.handle(target,baseRequest, request, response);
}
}
}
Starter.java
import java.io.IOException;
import java.util.logging.Logger;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.SimpleFormatter;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import com.example.config.AppConfig;
import com.example.handlers.CORSHandler;
import com.example.properties.*;
public class Starter {
public static void main( final String[] args ) throws Exception {
Server server = new Server( 8080 );
// Register and map the dispatcher servlet
final ServletHolder servletHolder = new ServletHolder( new CXFServlet() );
HandlerWrapper wrapper = new CORSHandler();
final ServletContextHandler context = new ServletContextHandler();
context.setContextPath( "/" );
context.addServlet( servletHolder, "/rest/*" );
context.addEventListener( new ContextLoaderListener() );
context.setInitParameter( "contextClass", AnnotationConfigWebApplicationContext.class.getName() );
context.setInitParameter( "contextConfigLocation", AppConfig.class.getName() );
wrapper.setHandler(context);
server.setHandler(wrapper);
server.start();
server.join();
}
}
I'm trying to create a basic servlet filter, I have created the filter and mapped it in the web.xml file but get filter not found exceptions.
Here's the web.xml file
<display-name>Disertation</display-name>
<filter>
<filter-name>AuthorizationFilter</filter-name>
<filter-class>Disertation.servlets.AuthorizationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthorizationFilter</filter-name>
<servlet-name>LoginServlet</servlet-name>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Here is the path for the filter class: Disertation/src/servlets/AuthorizationFilter.java
Am i missing something or is my configuration wrong?
EDIT: I took the com out of the web.xml and Here is the filter class
package servlets;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import JavaBeans.User;
/**
* Servlet Filter implementation class AuthorizationFilter.
* Its purpose is to check logged-in user's role and
* and accordingly allow or prevent access to the web resources.
*/
public class AuthorizationFilter implements Filter {
private FilterConfig filterConfig;
/**
* #see Filter#init(FilterConfig)
*/
#Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig=filterConfig;
}
/**
* #see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
ServletContext sc= filterConfig.getServletContext();
String username = request.getParameter("user");
String pwd = request.getParameter("pwd");
System.out.println("first check");
User user = new User (username, pwd, "employee");
System.out.println("is this getting here?");
request.setAttribute("role", user.getRole());
if (request.getAttribute("role").equals("employee")|| request.getAttribute("role").equals("admin"))
chain.doFilter(request, res);
}
/**
* #see Filter#destroy()
*/
#Override
public void destroy() {
filterConfig=null;
}
}
Your filter should be under the following directory Disertation/src/com/Disertation/servlets/AuthorizationFilter.java
to match your filter configuration or change your filter configuration to
<filter-class>servlets.AuthorizationFilter</filter- class>
Are you using the correct package? In AuthorizationFilter.java look for the package name that is declared at the top of the file. Then put that in your web.xml:
<filter-class>com.some.package.AuthorizationFilter</filter-class>
Also, there is a space in your closing tag after the hyphen
I wrote following code.
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
public class CacheFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse) response;
resp.setHeader("Cache-Control", "no-store, no-cache,must-revalidate,max-age=0");
resp.setHeader("Pragma", "no-cache");
chain.doFilter(request, response);
}
public void destroy() {
//delegate.destroy();
}
public void init(FilterConfig filterConfig) {
//delegate.destroy();
}
}
and here's the maping code in web.xml file
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.util.CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
This thing works but this filter gets applied for all the content, thus slowing my site's performance. I want this filter to be applied for content type "text/html" only. This can be easily achieved through ExpiresFilter like this
<init-param>
<param-name>ExpiresByType text/html</param-name>
<param-value>access plus 0 seconds</param-value>
</init-param>
but how to achieve it in this code?
I'd appreciate your earliest help.
I think you need to write Response Wrapper to modify the response from servlet-
See this links- http://www.java2s.com/Tutorial/Java/0400__Servlet/Filterthatusesaresponsewrappertoconvertalloutputtouppercase.htm
http://sqltech.cl/doc/oas10gR31/web.1013/b28959/filters.htm
http://software.it168.com/manual/servlet/0596005725_jsvltjspckbk-chp-19-sect-7.html
-Thanks
I have a simple Servlet that looks like this:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Bla extends HttpServlet {
private static final long serialVersionUID = 16252534;
#Override
public void init() throws ServletException {
System.out.println("init");
}
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("doGet");
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html><h1>It works!!</h1></html>");
}
#Override
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
System.out.println("service");
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost");
}
#Override
public void destroy() {
System.out.println("Destroy servlet");
}
}
and a web.xml that looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<web-app>
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Bla</servlet-name>
<servlet-class>instrurental_proj.servlets.Bla</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Bla</servlet-name>
<url-pattern>/bla</url-pattern>
</servlet-mapping>
</web-app>
When I visit the url http://localhost:8080/instrurental/bla, the following is printed out in the console:
init
service
but not doGet as I expect. Also, nothing is printed out in the browser! (I'm expecting it to say "It Works").
I've been struggling with this issue since yesterday. Does anyone have any suggestions, what could the problem be?
Why are u overriding the service method. There is no need of that. Remove it or else call
super.service(request,response);
REASON
Try to see the source of HttpServlet class. There you will see that depending on the method that is used to called the servlet i.e. GET/POST the necessary method doGet() or doPost() is called. And when the container actually receives a request it starts a new thread and and serves the client by calling service() method. So if you override it and don't call the super class' service method or define your own strategyhow GET will be called, doGet() method will never be called. Your request never calls doGet() method, its the service() method which calls it.