In order to use the security annotations of JSR-250 (RolesAllowed, PermitAll, DenyAll):
In Jersey, you would register the RolesAllowedDynamicFeature class.
In RESTeasy, you would use the web.xml config:
<context-param>
<param-name>resteasy.role.based.security</param-name>
<param-value>true</param-value>
</context-param>
Both of these rely on the implementation of SecurityContext.isUserInRole(), but it seems that WebSphere Liberty Profile does not.
How do we get this to work in WebSphere Liberty Profile (WLP)?
I used a minimal example:
Create a resource class/method with #RolesAllowed:
#Path("/rest")
public class HelloWorld {
#GET
#RolesAllowed("ANYTHING")
public Response hello() {
return Response.ok("Hello World").build();
}
}
Set your SecurityContextImpl in a filter, overriding isUserInRole() to always returns true;
Enable "role-based security" for the JAX-RS implementation. (Jersey or RESTeasy, etc as above. For WLP, I had to add the appSecurity-2.0 feature)
And you should have a working example.
However, it appears that WebSphere Liberty Profile returns 403 Forbidden even though isUserInRole returns true.
Does anyone know how to properly use the #RolesAllowed annotation in Liberty and what I might be missing?
Code
#ApplicationPath("/")
public class MyApplication extends Application {
public MyApplication() {}
}
#Provider
#Priority(Priorities.AUTHENTICATION)
public class AuthFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext ctx) throws IOException {
System.out.println("Setting SecurityContext..");
ctx.setSecurityContext(new MySecurityContext("someuser", "anyrole"));
}
}
public class MySecurityContext implements SecurityContext {
private String user;
private String role;
public static class MyPrincipal implements Principal {
private String name;
public MyPrincipal(String name) { this.name = name; }
#Override public String getName() { return name; }
}
public MySecurityContext(String user, String role) {
this.user = user;
this.role = role;
}
#Override public String getAuthenticationScheme() { return "BASIC"; }
#Override public Principal getUserPrincipal() { return new MyPrincipal(user); }
#Override public boolean isSecure() { return true; }
#Override
public boolean isUserInRole(String role) {
return true;
}
}
#Path("/test")
public class HelloWorld {
#GET
#RolesAllowed("doesntmatter")
public Response hello() {
return Response.ok("Hello World").build();
}
}
pom.xml (dependencies only)
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
server.xml
Code works with the appSecurity feature disabled. Does not work with it enabled.
<server description="test">
<featureManager>
<feature>jaxrs-2.0</feature>
<feature>localConnector-1.0</feature>
<!-- <feature>appSecurity-2.0</feature> -->
</featureManager>
<webApplication id="RoleTest" location="RoleTest.war" name="RoleTest"/>
<httpEndpoint httpPort="9081" httpsPort="9444" id="defaultHttpEndpoint"/>
<!-- below lines are required when appSecurity feature is loaded -->
<!--
<keyStore id="defaultKeyStore" password="{xor}Lz4sLCgwLTtu"/>
<basicRegistry id="basic" realm="BasicRegistry">
<user name="username" password="password" />
</basicRegistry>
-->
</server>
May be you can try this:
1 server.xml
<server description="test">
<featureManager>
<feature>jaxrs-2.0</feature>
<feature>appSecurity-2.0</feature>
</featureManager>
<webApplication id="RoleTest" location="RoleTest.war" name="RoleTest">
<application-bnd>
<security-role name="ANYTHING">
<user name="username" />
</security-role>
<security-role name="AuthenticationRole">
<user name="username" />
</security-role>
<security-role name="AllAuthenticated">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>
</webApplication>
<httpEndpoint httpPort="9081" httpsPort="9444" id="defaultHttpEndpoint" />
<basicRegistry id="basic" realm="BasicRegistry">
<user name="username" password="password" />
</basicRegistry>
</server>
2 Java Code
Create a MyApplication class and a resource class/method with #RolesAllowed:
#ApplicationPath("/")
public class MyApplication extends Application {
public MyApplication() {}
public Set<Class<?>> getClasses(){
Set<Class<?>> classes = new HashSet();
classes.add(HelloWorld.class);
return classes;
}
}
#Path("/rest")
public class HelloWorld {
#GET
#RolesAllowed("ANYTHING")
public Response hello() {
return Response.ok("Hello World").build();
}
}
3 web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee web-app_3_0.xsd"
version="3.0">
<display-name>Test Application</display-name>
<description>blablabla</description>
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>requestProcessorAttribute</param-name>
<param-value>requestProcessorAttribute_webcontainer</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>com.xxx.MyApplication</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SecurityContextApp</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>com.xxx.MyApplication</servlet-name>
<url-pattern>/xxx/*</url-pattern>
</servlet-mapping>
<security-constraint id="SecurityConstraint_2">
<web-resource-collection id="WebResourceCollection_2">
<web-resource-name>com.xxx.MyApplication
</web-resource-name>
<description>Protection area for Rest Servlet</description>
<url-pattern>/xxx/rest</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<user-data-constraint id="UserDataConstraint_2">
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
<auth-constraint id="AuthConstraint_2">
<role-name>AuthenticationRole</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>test</realm-name>
</login-config>
<security-role id="SecurityRole_1">
<description>blabla</description>
<role-name>ANYTHING</role-name>
</security-role>
<security-role id="SecurityRole_2">
<role-name>AuthenticationRole</role-name>
</security-role>
</web-app>
Any other issues, leave me a message.
Related
A Java servlet application has been changed so that it no longer requires certificate authentication.
That part works correctly. However, the application no longer connects to the database and throws the following exception:
> REMOTE USER IS null MY URL is 0:0:0:0:0:0:0:1 NULL GENERICPRINCIPAL
> Apr 01, 2021 12:43:11 PM org.apache.catalina.core.StandardWrapperValve
> invoke SEVERE: Servlet.service() for servlet
> [com.harris.cpd.resource.ApplicationConfig] in context with path
> [/cpd] threw exception [java.lang.NullPointerException] with root
> cause java.lang.NullPointerException at
> com.harris.cpd.resource.CPDResource.getTomcatUserRole(CPDResource.java:116)
The following is web.xml with changes shown in comments.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>cpd</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>chemicals.html</welcome-file>
</welcome-file-list>
<!-- THIS IS NEW CODE -->
<filter>
<filter-name>CPDAuthenticationFilter</filter-name>
<filter-class>com.harris.cpd.filter.CPDAuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CPDAuthenticationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- THIS SECTION IS NEW CODE -->
<servlet>
<servlet-name>cpd</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>cpd</servlet-name>
<url-pattern>/cpd/*</url-pattern>
</servlet-mapping>
<!-- THIS SECTION IS NOW COMMENTED OUT
<security-constraint>
<web-resource-collection>
<web-resource-name>BasicSecurity</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<description>Authorized role is librarian</description>
<role-name>DOMAIN_LIBRARIAN</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>BasicSecurity</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description>Authorized role is guest and librarian</description>
<role-name>DOMAIN_LIBRARIAN</role-name>
<role-name>DOMAIN_GUEST</role-name>
</auth-constraint>
</security-constraint> -->
<!-- THIS IS NEW CODE AND PROVIDES THE BASIC LOGIN -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Login</realm-name>
</login-config>
<!-- THIS CODE IS NOW COMMENTED OUT
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>IAASecurityRealm</realm-name>
</login-config> -->
<security-role>
<description>A Guest User in the system</description>
<role-name>DOMAIN_GUEST</role-name>
</security-role>
<security-role>
<description>A Guest User in the system</description>
<role-name>DOMAIN_LIBRARIAN</role-name>
</security-role>
<!--
<security-role>
<description>A Guest User in the system</description>
<role-name>GUEST</role-name>
</security-role>
<security-role>
<description>A Guest User in the system</description>
<role-name>LIBRARIAN</role-name>
</security-role>
-->
</web-app>
And here is CPDAuthenticationFilter.java which is the filter code.
One line was deleted below:
UserRole role = auth.authenticate(authCredentials);
The following line replaced it, hard-coding "role":
UserRole role = UserRole.DOMAIN_LIBRARIAN;
package com.harris.cpd.filter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
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;
import javax.servlet.http.HttpServletResponse;
import com.harris.cpd.authentication.AuthenticationService;
import com.harris.cpd.authentication.UserRole;
//#WebFilter(filterName="authentication", urlPatterns="/resources/*")
public class CPDAuthenticationFilter implements Filter {
private final static Logger logger = Logger.getLogger(CPDAuthenticationFilter.class.getPackage().getName());
public static final String AUTHENTICATION_ATTR = "cpd.authenticate";
public static final String USER_ROLE_ATTR = "cpd.user.role";
/* (non-Javadoc)
* #see javax.servlet.Filter#destroy()
*/
#Override
public void destroy() {
}
/* (non-Javadoc)
* #see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter)
throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (httpServletRequest.isUserInRole(UserRole.DOMAIN_GUEST.toString())) {
logger.log(Level.INFO, "found a guest user");
}
else if (httpServletRequest.isUserInRole(UserRole.DOMAIN_LIBRARIAN.toString())) {
logger.log(Level.INFO, "found a domain_librarian user");
}
else {
logger.log(Level.INFO, "found invalid user: "+httpServletRequest.getRemoteUser());
}
String authCredentials = httpServletRequest.getHeader(AUTHENTICATION_ATTR);
AuthenticationService auth = new AuthenticationService();
// CRM : TEST access 8080 without login:
//UserRole role = auth.authenticate(authCredentials);
UserRole role = UserRole.DOMAIN_LIBRARIAN; //CGN 3-25 TURNING OFF WHAT CHRIS HAD
logger.log(Level.INFO, "user role: " + role);
if (role.equals(UserRole.DOMAIN_GUEST) || role.equals(UserRole.DOMAIN_LIBRARIAN)) {
request.setAttribute(USER_ROLE_ATTR, role);
filter.doFilter(request, response);
} else {
if (response instanceof HttpServletResponse) {
logger.log(Level.INFO, "failed BASIC authentication");
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
}
}
/* (non-Javadoc)
* #see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
#Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("init the authentication filter (RestAuthenticationFilter)");
}
}
The errors that shows up on the Chrome debug tools for the client side:
-- LOADING APP (index.html) --
:8080/cpd/resources/categories:1 Failed to load resource: the server responded with a status of 500 ()
angular.js:14516 -- db: getProcessCategories url:http://localhost:8080/cpd/resources/categories procCats 500 failed --
So the problem presents itself as servlet error, and the database is not connecting, returning anything, with just the changes I have shown above.
I don't think this exception was related to database connection.
according to the exception which you have faced.
getTomcatUserRole(CPDResource.java:116)
I think there is another class like CPDResource.java that has been affected by this change
<!--
<security-role>
<description>A Guest User in the system</description>
<role-name>GUEST</role-name>
</security-role>
<security-role>
<description>A Guest User in the system</description>
<role-name>LIBRARIAN</role-name>
</security-role>
-->
and you should set it as a hardcode instead of getting from roles as before.
I am new for spring mvc with soap web service.
I have made one web project using spring-mvc, which has #Controller that can handle website view (using model). For business logic, have used #Service and #Repository class.
Now, I am making web service which has same business logic that is working for website view. For that I made one web service class and #Autowired existing #Service for business logic. But that #Autowired class referencing null.
Below is my sample project code, In which
I have made service implementation class and autowired service class for business logic and tomcat catalina com.sun.xml.ws.server.sei.TieHandler.createResponse null
java.lang.NullPointerException
at com.springmvcmaven.ws.producer.hello.HelloWSImpl.hello(HelloWSImpl.java:34)
dispatcher-servlet.xml
<context:annotation-config/>
<context:component-scan base-package="com.springmvcmaven" />
<mvc:annotation-driven/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/"
p:suffix=".jsp" />
pom.xml
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.2.10</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
sun-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>
<endpoints version="2.0" xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">
<endpoint implementation="com.springmvcmaven.ws.producer.hello.HelloWSImpl" name="hello" url-pattern="/hello"/>
</endpoints>
Model Class - User.java
public class User
{
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Model Controller for web - HomeController.java
#Controller
public class HomeController
{
/**
* Simply selects the home view to render by returning its name.
* #param locale
* #param model
* #return
*/
#Autowired
#Qualifier(value = "homeService")
#Lazy(true)
private HomeService service;
#RequestMapping(value = "/home.do", method = RequestMethod.GET)
public String home(Locale locale, Model model)
{
System.out.println("Home Page Requested, locale = " + locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
return "home";
}
#RequestMapping(value = "/user.do", method = RequestMethod.POST)
public String user(#Validated User user, Model model)
{
System.out.println("User Page Requested");
model.addAttribute("userName", service.wsCall(user));
return "user";
}
}
HomeService.java
public interface HomeService
{
public String wsCall(User user);
}
HomeServiceImpl.java
#Service(value = "homeService")
public class HomeServiceImpl implements HomeService
{
#Override
public String wsCall(User user)
{
return "Bravo " + user.getUserName() + " !!";
}
}
Web service class interface - HelloWS.java
#WebService(name="hello")
#SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWS
{
#WebMethod
public String hello(User user);
}
web service implementation class - HelloWSImpl.java
#WebService(endpointInterface = "com.springmvcmaven.ws.producer.hello.HelloWS")
public class HelloWSImpl implements HelloWS
{
#Autowired
#Qualifier(value = "homeService")
#Lazy(true)
private HomeService service;
/**
* This is a sample web service operation
* #param user
* #return
*/
#Override
public String hello(User user)
{
return service.wsCall(user);
}
}
web service client call
public class HelloClient
{
public static void main(String[] args)
{
try
{
URL wsdlURL = new URL("http://localhost:8080/SpringMVCMaven/hello?wsdl");
//check above URL in browser, you should see WSDL file
//creating QName using targetNamespace and name
QName qname = new QName("http://hello.producer.ws.springmvcmaven.com/", "HelloWSImplService");
Service service = Service.create(wsdlURL, qname);
//We need to pass interface and model beans to client
HelloWS helloWS = service.getPort(HelloWS.class);
User user = new User();
user.setUserName("JIya");
System.out.println(helloWS.hello(user));
}
catch(Exception e)
{
System.out.println("EXCEPTION => \n" + e);
}
}
}
Kindly direct me, what I am missing from these code. Is this proper way ?
Thanks in advance.
I have created a REST webservice 'JSONService' ( using Jersey implementation JAX-RS) with a POST method and created 'JerseyClientPost'.
What I am trying to achieve is to send a POST from my JerseyClientPost. Getting all values into a 'player' object and sending along with response back. But while trying to send the POST request from the postman, it throws
HTTP Status 404 - Not Found, The requested resource is not available.
Any pointers to address this problem will be much appreciated ?
Request Url : http://localhost:8080/WeekendSoccer/test/register/create
Following are my environment details:
JDK 1.7.0_79,
Tomcat Server v7.0,
Jersey (jaxrs-ri-2.25.1),
Web.xml
//REST Resource is given below
package webService;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import dto.RegisterPlayer;
#Path("/register")
public class JSONService {
#POST
#Path("/create")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response createPlayerInJSON(RegisterPlayer player) {
String result = "Player Created : " +player;
return Response.status(201).entity(result).build();
}
}
//Below is the Jersey Client Post
package dao;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
public class JerseyClientPost {
public static void main(String[] args) {
try {
RegisterPlayer player = new RegisterPlayer();
player.setName("Link");
player.setEmail("link#test.com");
player.setCompany("Test Ltd");
Client client = ClientBuilder.newClient(new ClientConfig().register( LoggingFilter.class ));
WebTarget webTarget
= client.target("http://localhost:8080/WeekendSoccer/test");
WebTarget playerWebTarget
= webTarget.path("/register/create");
Invocation.Builder invocationBuilder
= playerWebTarget.request(MediaType.APPLICATION_JSON);
Response response
= invocationBuilder
.post(Entity.entity(player,MediaType.APPLICATION_JSON));
if (response.getStatus() != 201) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));
} catch (Exception e) {
e.printStackTrace();
}
}
}
// RegisterPlayer model class with getters, setters
public class RegisterPlayer implements Serializable{
private String name;
private String email;
private String company;
public RegisterPlayer()
{
}
public RegisterPlayer(String name, String email, String company)
{
super();
this.name = name;
this.email = email;
this.company = company;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
....
}
// Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>WeekendSoccer</display-name>
<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>
<servlet>
<servlet-name>Register Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>webService</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Register Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>JSON Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>dao</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JSON Service</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>
</web-app>
//Listed all jars
aopalliance-repackaged-2.5.0-b32.jar
gson-2.2.2.jar
hk2-api-2.5.0-b32.jar
hk2-locator-2.5.0-b32.jar
hk2-utils-2.5.0-b32.jar
jackson-annotations-2.3.2.jar
jackson-core-2.3.2.jar
jackson-databind-2.3.2.jar
jackson-jaxrs-base-2.3.2.jar
jackson-jaxrs-json-provider-2.3.2.jar
jackson-module-jaxb-annotations-2.3.2.jar
javassist-3.20.0-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.5.0-b32.jar
javax.servlet-api-3.0.1.jar
javax.ws.rs-api-2.0.1.jar
jaxb-api-2.2.7.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet-core.jar
jersey-container-servlet.jar
jersey-entity-filtering-2.17.jar
jersey-guava-2.25.1.jar
jersey-media-jaxb.jar
jersey-media-json-jackson-2.17.jar
jersey-server.jar
mysql-connector-java-5.1.40-bin.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
persistence-api-1.0.jar
validation-api-1.1.0.Final.jar
Firstly, I have never tested your client side code but I guess your problem is about server side and tested in Postman. you should add #XmlRootElement annotation in your pojo class RegisterPlayer like that:
#XmlRootElement
public class RegisterPlayer implements Serializable{
private String name;
private String email;
private String company;
public RegisterPlayer()
{
}
public RegisterPlayer(String name, String email, String company)
{
super();
this.name = name;
this.email = email;
this.company = company;
}
and added these dependencies in pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
If you already have these jars it is fine. It works for me right now. I hope it helps to you.
jackson-core-2.9.3.jar
jackson-mapper-asl-1.9.13.jar
jackson-core-asl-1.9.13.jar
asm-3.3.1.jar
jersey-bundle-1.19.4.jar
jsr311-api-1.1.1.jar
json-20170516.jar
jersey-server-1.19.4.jar
jersey-core-1.19.4.jar
jersey-multipart-1.19.4.jar
mimepull-1.9.3.jar
jackson-annotations-2.7.0.jar
jackson-databind-2.7.0.jar
I'm still not sure, why do you have following mapping in web.xml ? As theren't any servlet class associated with this servlet name. You should removed them
<servlet-mapping>
<servlet-name>JSON Service</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>
I see you have following entries and they do have servlet class associated.
<servlet-mapping>
<servlet-name>Register Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
That means, you target url should be
http://localhost:8080/WeekendSoccer/rest/register/create
instead of
http://localhost:8080/WeekendSoccer/test/register/create
I had a Spring MVC project that was using XML for all the config stuff but I remove all the XML and made them into JavaConfig (Everything but Spring Security). Once I try to get Spring Security working I could see that my project was blowing up looking for applicationContext.xml in WEB.INF. I dont have anything pointing to that so who do I need it>?
my secuirty.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<global-method-security pre-post-annotations="enabled" />
<http use-expressions="true">
<intercept-url access="hasRole('ROLE_VERIFIED_MEMBER')" pattern="/mrequest**" />
<intercept-url pattern='/*' access='permitAll' />
<form-login default-target-url="/visit" />
<logout logout-success-url="/" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="cpilling04#aol.com.dev" password="testing" authorities="ROLE_VERIFIED_MEMBER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Here is my webconfig:
#Configuration
#EnableWebMvc
#Import(DatabaseConfig.class)
#ImportResource("/WEB-INF/spring/secuirty.xml")
public class WebMVCConfig extends WebMvcConfigurerAdapter {
private static final String MESSAGE_SOURCE = "/WEB-INF/classes/messages";
private static final Logger logger = LoggerFactory.getLogger(WebMVCConfig.class);
#Bean
public ViewResolver resolver() {
UrlBasedViewResolver url = new UrlBasedViewResolver();
url.setPrefix("/WEB-INF/view/");
url.setViewClass(JstlView.class);
url.setSuffix(".jsp");
return url;
}
#Bean(name = "messageSource")
public MessageSource configureMessageSource() {
logger.debug("setting up message source");
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver lr = new SessionLocaleResolver();
lr.setDefaultLocale(Locale.ENGLISH);
return lr;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.debug("setting up resource handlers");
registry.addResourceHandler("/resources/").addResourceLocations("/resources/**");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
logger.debug("configureDefaultServletHandling");
configurer.enable();
}
#Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
}
#Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.put("org.springframework.web.servlet.PageNotFound", "p404");
mappings.put("org.springframework.dao.DataAccessException", "dataAccessFailure");
mappings.put("org.springframework.transaction.TransactionException", "dataAccessFailure");
b.setExceptionMappings(mappings);
return b;
}
#Bean
public RequestTrackerConfig requestTrackerConfig()
{
RequestTrackerConfig tr = new RequestTrackerConfig();
tr.setPassword("Waiting#$");
tr.setUrl("https://uftwfrt01-dev.uftmasterad.org/REST/1.0");
tr.setUser("root");
return tr;
}
}
Here is my DatabaseConfig:
#Configuration
#EnableTransactionManagement
#ComponentScan(basePackages= "org.uftwf")
#PropertySource(value = "classpath:application.properties")
public class DatabaseConfig {
private static final Logger logger = LoggerFactory.getLogger(DatabaseConfig.class);
#Value("${jdbc.driverClassName}")
private String driverClassName;
#Value("${jdbc.url}")
private String url;
#Value("${jdbc.username}")
private String username;
#Value("${jdbc.password}")
private String password;
#Value("${hibernate.dialect}")
private String hibernateDialect;
#Value("${hibernate.show_sql}")
private String hibernateShowSql;
#Value("${hibernate.hbm2ddl.auto}")
private String hibernateHbm2ddlAuto;
#Bean
public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer()
{
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocation(new ClassPathResource("application.properties"));
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}
#Bean
public DataSource dataSource() {
try {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:jboss/datasources/mySQLDB");
}
catch (Exception e)
{
}
return null;
}
#Bean
public SessionFactory sessionFactory()
{
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setHibernateProperties(getHibernateProperties());
factoryBean.setPackagesToScan("org.uftwf.inquiry.model");
try {
factoryBean.afterPropertiesSet();
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return factoryBean.getObject();
}
#Bean
public Properties getHibernateProperties()
{
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.format_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
hibernateProperties.setProperty("javax.persistence.validation.mode", "none");
//Audit History flags
hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", "true");
hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", "true");
return hibernateProperties;
}
#Bean
public HibernateTransactionManager hibernateTransactionManager()
{
HibernateTransactionManager htm = new HibernateTransactionManager();
htm.setSessionFactory(sessionFactory());
htm.afterPropertiesSet();
return htm;
}
}
and my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Inquiry</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.uftwf.inquiry.config, org.uftwf.inquiry.controller</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
<security-constraint>
<web-resource-collection>
<web-resource-name>securedapp</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
-->
</web-app>
So I dont see anything looking for applicationContext.xml .... can someone please tell me why I need it to add it and once I did it started to work
Spring Application contexts are hierarchical. The typical arrangement in a web app is that the context loader listener bootstraps your AC and makes them available 'globally', then each individual DispatcherServlet will have its own child application context that can 'see' all the beans (typically services, data sources, etc.) from the context loader listener's AC. In all cases - when specifying the ContextLoaderListener or the DispatcherServlet - Spring will automatically (based on convention) look for an XML application context and attempt to load it. Usually you can disable this by simply specifying an empty contextConfigLocation param ("") or by telling it that it should expect a Java config class, instead (contextClass attribute). BTW, it is possible to have multiple DispatcherServlets. You might, for example, use Spring Integration's inbound HTTP adapter with one, a Spring Web Services endpoint with another, Spring MVC app on another and a Spring HTTP invoker endpoint on another still, and they'd all be exposed via a DispatcherServlet. You could, theoretically, make them all work in the same DispatcherServlet, but the isolation helps keep things less cluttered and they can all share the same single instances of global, more expensive beans, like DataSources.
You configured ContextLoaderListener in your web.xml, but haven't specified the contextConfigLocation context-param. The behaviour in this case is described by the javadoc of that class:
Processes a "contextConfigLocation" context-param [...] If not explicitly specified, the context implementation is supposed to use a default location (with XmlWebApplicationContext: "/WEB-INF/applicationContext.xml").
So, it is the ContextLoaderListener that requires a applicationContext.xml.
To make sure your app doesn't use applicationContext.xml you can do something similar to this. You can see how this all goes together here.
public class MyInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
//Clear out reference to applicationContext.xml
servletContext.setInitParameter("contextConfigLocation", "");
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(MySpringRootConfiguration.class);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
//Add jersey or any other servlets
ServletContainer jerseyServlet = new ServletContainer(new RestApplication());
Dynamic servlet = servletContext.addServlet("jersey-servlet", jerseyServlet);
servlet.addMapping("/api/*");
servlet.setLoadOnStartup(1);
}
}
I'm trying to make very simple Spring 3 + JSF2.1 integration according to examples I googled in the web.
So here is my code:
My HTML submitted to actionController.actionSubmitted() method:
<h:form>
<h:message for="textPanel" style="color:red;" />
<h:panelGrid columns="3" rows="5" id="textPanel">
//all my bean prperties mapped to HTML code.
</h:panelGrid>
<h:commandButton value="Submit" action="#{actionController.actionSubmitted}" />
</h:form>
now the Action Controller itself:
#ManagedBean(name="actionController")
#SessionScoped
public class ActionController implements Serializable{
#ManagedProperty(value="#{user}")
User user;
#ManagedProperty(value="#{mailService}")
MailService mailService;
public void setMailService(MailService mailService) {
this.mailService = mailService;
}
public void setUser(User user) {
this.user = user;
}
private static final long serialVersionUID = 1L;
public ActionController() {}
public String actionSubmitted(){
System.out.println(user.getEmail());
mailService.sendUserMail(user);
return "success";
}
}
Now my bean Spring:
public interface MailService {
void sendUserMail(User user);
}
public class MailServiceImpl implements MailService{
#Override
public void sendUserMail(User user) {
System.out.println("Mail to "+user.getEmail()+" sent." );
}
}
This is my web.xml
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<!-- Welcome page -->
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<!-- JSF mapping -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
my applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="mailService" class="com.vanilla.jsf.services.MailServiceImpl">
</bean>
</beans>
my faces-config.xml is the following:
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
<message-bundle>
com.vanilla.jsf.validators.MyMessages
</message-bundle>
</application>
<managed-bean>
<managed-bean-name>actionController</managed-bean-name>
<managed-bean-class>com.vanilla.jsf.controllers.ActionController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>mailService</property-name>
<value>#{mailService}</value>
</managed-property>
</managed-bean>
<navigation-rule>
<from-view-id>index.xhtml</from-view-id>
<navigation-case>
<from-action>#{actionController.actionSubmitted}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>submitted.xhtml</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
My Problem is that I'm getting NullPointerException because my mailService Spring bean is null.
public String actionSubmitted(){
System.out.println(user.getEmail());
//mailService is null Getting NullPointerException
mailService.sendUserMail(user);
return "success";
}
I added getter for mail servie and the problem was solved. I do't know why this getter is required, but it works.