Tomcat displaying welcome-page before filter for jsp is executed - tomcat6

I am using Tomcat 6.0.36 and the welcome-page is /Login.jsp
I have a filter in place so that it can display a different login page for mobile devices.
It works with URL mywebsite.com/Login.jsp, but the filter is bypassed when the URL is just mywebsite.com.
Is there a way to force it to execute?
I have found this page but it doesn't work in my case:
How to map a filter for welcome-file in web.xml for Tomcat?
Thanks
My web.xml:
<welcome-file-list>
<welcome-file>/Login.jsp</welcome-file>
</welcome-file-list>
...
<filter>
<display-name>LoginPageFilter</display-name>
<filter-name>LoginPageFilter</filter-name>
<filter-class>filters.LoginPageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginPageFilter</filter-name>
<url-pattern>/Login.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
The filter - I had deleted it and put one quickly back together
public class LoginPageFilter implements Filter
{
public LoginPageFilter() { }
public void init ( FilterConfig fConfig ) throws ServletException { }
public void doFilter ( ServletRequest request, ServletResponse response,
FilterChain chain ) throws IOException,
ServletException
{
System.out.println ( "Filter being executed" );
chain.doFilter(request, response);
}
public void destroy() { }
}
If the URL is
http://localhost:8080/gymfit/Login.jsp
then the message is printed to the console.
When the URL is
http://localhost:8080/gymfit/
the same page is displayed but the message is not printed out to the console

look at this line, this means only the request to '/Login.jsp' will the filter being executed
<url-pattern>/Login.jsp</url-pattern>
if you want to apply this filter to all the path, change the config to:
<url-pattern>/*</url-pattern>

Related

How to remove # from URL , SpringBoot & AngularJs application?

This is my TuckeyRewriteFilter filter class
public class TuckeyRewriteFilter extends org.tuckey.web.filters.urlrewrite.UrlRewriteFilter {
#Override
protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
String confPath = filterConfig.getInitParameter("confPath");
ServletContext context = filterConfig.getServletContext();
try {
final URL confUrl = getClass().getClassLoader().getResource(confPath);
final InputStream config = getClass().getClassLoader().getResourceAsStream(confPath);
Conf conf = new Conf(context, config, confPath, confUrl.toString(), false);
checkConf(conf);
} catch (Throwable e) {
throw new ServletException(e);
}
}
}
This is my springboot main class
public class AdminWebApplication {
public static final String REWRITE_FILTER_NAME = "rewriteFilter";
public static final String REWRITE_FILTER_CONF_PATH = "urlrewrite.xml";
#Autowired
ApplicationContext applicationContext;
public static void main(String[] args) {
SpringApplication.run(AdminWebApplication.class, args);
}
#Bean
public ObjectMapper createObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
applicationContext.getAutowireCapableBeanFactory().autowireBean(objectMapper);
return objectMapper;
}
#Bean
public FilterRegistrationBean rewriteFilterConfig() {
FilterRegistrationBean reg = new FilterRegistrationBean();
reg.setName(REWRITE_FILTER_NAME);
reg.setFilter(new TuckeyRewriteFilter());
reg.addInitParameter("confPath", REWRITE_FILTER_CONF_PATH);
reg.addInitParameter("confReloadCheckInterval", "-1");
reg.addInitParameter("statusPath", "/redirect");
reg.addInitParameter("statusEnabledOnHosts", "*");
reg.addInitParameter("logLevel", "WARN");
return reg;
}
}
This is my urlrewrite.xml
this file is from resources folder
configuration is works fine, loading login page, but still I have to pass /#login, then it redirect to /login URL, but on browser refresh I ma getting 404 error.
index.html, I have added , I don't want extra domain name after my port id.
<urlrewrite default-match-type="wildcard">
<rule>
<from>/login</from>
<to>/login.html</to>//As of now only configured for login page.
</rule>
<rule>
<from>/contact</from>
<to>/index.html</to>
</rule>
</urlrewrite>
In your js router file (config phase) you need to add:
$locationProvider.hashPrefix('');
$locationProvider.html5Mode(true);
and in your index.html file, you need to add:
<base href="/">
Update 1
After implementing above on client side, you need to configure url mapping on server side as well. With # , the server ignores whatever is followed after it.
http://localhost:8080/#i_will_be_ignored/and_so_do_i
So, when you configure angularjs to remove # from URLs, your above request
http://localhost:8080/i_will_be_ignored/and_so_do_i
will now hit server with #path('i_will_be_ignored') . Now, that will give you 404 because you never mapped any API for it. Thats the reason, you are getting 404 on page refresh.
You need to map all the URLs that doesn't match to index.html followed by the unmatched url. Once that's done, angularjs will take it from there and redirects to appropriate route . I hope this will help you.
Something like this will help you out here

angularjs rest API Spring

i have a problem with rest API in angularjs.
web.xml
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>com.mycompany.xxxx.userInterface.servlet.SpringServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
SpringServlet.class
#Override
public void init() throws ServletException
{
super.init();
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
SpringBeanReader.getInstance().setApplicationContext(applicationContext);
//SpringBeanReader.getInstance().getApplicationContext().getBean(")
}
I have problems when I call api.
controller.js
.service('ApiCall', ['$http', function ($http){
//Get All Employees
this.getEmployees = function () {
console.log('dentro service.js');
return $http.get("/utenti/all");
}
}])
.controller("DataTable",['$scope','ApiCall',
function($scope,ApiCall){
$scope.persons = ApiCall.getEmployees();
}])
Controller.class
#Path("/utenti")
public class UtentiController {
#Path("/all")
#GET
#Produces("application/json")
public JSONArray getAll() {
/**** code for JSON array ***/
}
The code "$http.get("/utenti/all");" return error
HTTP Status [404] – [Not Found]
Type Status Report
Message /foodplan/utenti/all
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Thanks to all.

Is it possible to redirect 404 to index.html on Google App Engine Standard in a Java app?

I'm trying to deploy an Angular 4 app with a Java backend on Google App Engine (standard). Everything works fine except when I try to reload the page. What happens is that a request to e.g. myapp.com/some/page should be redirected to myapp.com/index.html for the Angular app to respond.
As far as I can see, this would be possible if using the app.yaml configuration file which is used for all supported languages except Java (which uses appengine-web.xml and web.xml).
Can this be done with appengine-web.xml? In any other way?
If you want to keep the PathLocationStrategy which is the default "HTML5 pushState" style, you need to implement a redirect on the backend side. Basically you need to add a filter or servlet with "/*" as the URL pattern with the following behavior:
public class SinglePageAppFilter implements Filter {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
RequestDispatcher dispatcher = servletRequest.getRequestDispatcher("/");
dispatcher.forward(servletRequest, servletResponse);
}
}
Yes you have to use the HashLocationStrategy instead of the default PathLocationStrategy.
Angular's documentation: https://angular.io/guide/router#appendix-locationstrategy-and-browser-url-styles
Basically, you just have to tell the RouterModule to use HashLocationStrategy in your AppRoutingModule:
#NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})],
exports: [RouterModule]
})
export class AppRoutingModule {
}
I hope it helps
As a follow up to Gwendal Le Cren's answer, I did this and needed a few more things with the filter, so I'll put them below.
// Filter all paths.
#WebFilter("/*")
public class SinglePageAppFilter implements Filter {
#Override
public void doFilter(
ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
// Get the end part of the path e.g. /api for API requests, /devices for the devices page etc.
String path = ((HttpServletRequest) servletRequest).getServletPath();
// Continue with the intended action if an API request.
if (path.startsWith("/api")) {
filterChain.doFilter(servletRequest, servletResponse);
}
// Otherwise, send the result as if requesting the '/' path.
else {
RequestDispatcher dispatcher = servletRequest.getRequestDispatcher("/");
dispatcher.forward(servletRequest, servletResponse);
}
}
#Override
public void init(FilterConfig filterConfig) {}
#Override
public void destroy() {}
}

Cross-Origin Request Blocked, angularjs rest call to jersey api

I'm completely stumped. I am very new to AngularJS and I am trying to make a rest call to my jersey server api but I am having no luck. It works using curl or Advanced Rest client (Chrome browser add-on). However I recevied the following when attempting to hit my rest using my angularjs app..
"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/JerseyDemos/rest/employees. (Reason: CORS header 'Access-Control-Allow-Origin' missing)."
CLIENT: snippet of my angularjs code
$scope.login = function() {
This lets me connect to my server on a different domain
$http.defaults.headers.common['Authorization'] = 'Basic ' + Base64.encode('username' + ':' + 'password');
$http({method: 'GET', url: 'http://localhost:8080/JerseyDemos/rest/employees'}).
success(function(data) {
console.log(data)
}).
SERVER: I am using jersey framework
Heres my CORS Filter...
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
public class CorsResponseFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext request,
ContainerResponseContext response) throws IOException {
response.getHeaders().add("Access-Control-Allow-Origin", "*");
response.getHeaders().add("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization");
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}
Application class to register my CORS Filter
import com.howtodoinjava.jersey.provider.CorsResponseFilter;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import com.howtodoinjava.jersey.provider.AuthenticationFilter;
import com.howtodoinjava.jersey.provider.GsonMessageBodyHandler;
public class CustomApplication extends ResourceConfig {
public CustomApplication()
{
packages("com.howtodoinjava.jersey");
register(CorsResponseFilter.class);
register(LoggingFilter.class);
register(GsonMessageBodyHandler.class);
register(AuthenticationFilter.class);
}
}
Web.xml
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.howtodoinjava.jersey.CustomApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Employee rest snippet
#Provider
#Path("/employees")
public class JerseyService {
#Path("/all")
#RolesAllowed("ADMIN")
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getAllEmployees()
{
Employees list = new Employees();
list.setEmployeeList(new ArrayList<Employee>());
list.getEmployeeList().add(new Employee(1, "Lokesh Gupta"));
list.getEmployeeList().add(new Employee(2, "Alex Kolenchiskey"));
list.getEmployeeList().add(new Employee(3, "David Kameron"));
return Response.status(200).entity(list).header("Access-Control-Allow-Origin", "GET, POST, PUT, DELETE, OPTIONS, HEAD").build();
}
This is a very common error for people who are just getting started with Web Services, it’s really simple to solve but sometimes developers spend hours struggling to find a solution. It happens when you create a web service and tries to access it from a different application, it won’t work because you don’t have Cross-Origin Resource Sharing (CORS) enabled, which means an application loaded in one domain cannot interact with resources from a different domain. All you have to do is to enable CORS.
How you can active it will depending on your scenario, in this tutorial I’m going to show how to enable CORS for a Java EE application running on Glassfish, I’m assuming you have an EJB RESTful web service similar to this one, and when other applications tries to consume it you see the Cross-Origin Request Blocked error on your firebug console, in this case all you have to do is to create a filter in your application, just create a class exactly like this one on your project:
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 CORSFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
final HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, x-auth-token, "
+ "Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
filterChain.doFilter(servletRequest, servletResponse);
}
#Override
public void destroy() {
}
}
Now you have to register the filter in your web.xml, copy the following code and replace “yourPackage” with your actual package name:
<filter>
<filter-name>cors</filter-name>
<filter-class>yourPackage.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
That’s it! Now your application will allow its resources to be shared with other domains.
Other Cross-Origin Request fix..

Spring REST call gives 302 redirect

I am using angularjs to make a REST call to my tomcat backend managed by Spring. But my server code never seems to get the call and the browser gets a 302 with "index.html" appended at the end of the url. For example, if my initial call was "localhost:8080/api/search/someString", browser receives a 302 redirect to "localhost:8080/api/search/someString/index.html", which then redirects to "localhost:8080/api/search/someString/index.html/index.html".
This keeps happening until a "Too many redirects" error occurs and it fails. Any ideas anyone?
Here is my web.xml:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
<url-pattern>/api/*</url-pattern>
<url-pattern>/page/*</url-pattern>
</servlet-mapping>
Angular call:
search: function (searchStr) {
return $http.get("/api/search/"+searchStr);
}
Rest Controller:
#RestController
public class SearchResource {
#Autowired
private ItemService itemService;
#RequestMapping(value = "/api/search/{searchStr}", method = RequestMethod.GET)
public List<Item> getItemsBasedOnSearchString(#PathVariable String searchStr) {
return itemService.getAllItems();
}
public ItemService getItemService() {
return itemService;
}
public void setItemService(ItemService itemService) {
this.itemService = itemService;
}
}
Sometimes you can make the stupidest of mistakes! I changed the RequestMapping annotation from "/api/search" to "/search" and it works.
Thanks.

Resources