I had written a very small rest service. When I am trying through the rest cilent, I am getting the error as "method not supported". Can anybody, please suggest me on this.
**controller class**
#Controller
#RequestMapping("/movie")
public class MovieController {
#RequestMapping(value="/{name}", method = RequestMethod.PUT, consumes="application/json")
public #ResponseBody Student getMovie(#PathVariable String name, ModelMap model, #RequestBody Student student, HttpSession session) {
Map<Integer, Student> empData = new HashMap<Integer, Student>();
empData.put(1, student);
return student;
}
}
**Request I am sending throught Rest DHC Client**
URL: http://localhost:8081/SpringMVC/movie/test
method selected: PUT
Headers: Content-Type:application/json
Body: {
"userId":"21",
"firstName":"srinu",
"lastName":"nivas"
}
I use only Jersey to do what you want.
My web.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" 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 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>appName</display-name>
<filter>
<filter-name>jersey</filter-name>
<filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.appName.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/Pages/</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(resources|(Pages))/.*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
And in the rest class i return a Viewable:
My rest class:
#GET
#Path("/PathToAccessPage")
#Produces(MediaType.TEXT_HTML)
public Viewable GetMyClassPage(#Context HttpServletRequest request, #Context UriInfo ui, #Context HttpHeaders hh) {
try {
MyClass myClass = getMyClass();
return new Viewable("/page", myClass);
}
catch (Exception ex) {
return new Viewable("/error", "Error processing request: " + ex.getMessage());
}
}
Hope you help!
Finally, I got the solution. I didn't import the below two jars.
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
As I am using spring MVC and as you can see in the above code, I am giving as consumes=application/json, I thought springMVC will take care of that. It's my mistake and also, I think the error which was renedered by spring, should be something specific to this. Anyway, got the solution. Thanks all for the help.
Related
I have a jetty servlet set of pages all set up and working.
to get to the landing page, you have to enter the full url http://127.0.0.1/console/console.jsp
everything is fine for my context "console".
I wanted to add a handler for the root url, so I could just put in a host and it would redirect to the above url.
I got that working, except it seems that every request comes through my root path handler as well and it messes up all the other requests to the real jsp pages.
How do I keep it from doing that, or what do I do differently?
my web.xml...
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description></description>
<servlet-name>console</servlet-name>
<servlet-class>net.console.Consoleservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>console</servlet-name>
<url-pattern>/console</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<servlet-name>redirect</servlet-name>
<servlet-class>net.console.Redirectservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>redirect</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
slimmed down version of my redirect servlet...
public class Redirectservlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
{
static final long serialVersionUID = 1L;
public Redirectservlet()
{
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
String redirect_path = "http://127.0.0.1/console/console.jsp";
response.sendRedirect(redirect_path);
}
catch (Exception e)
{
}
}
Try using welcome-files instead of your RedirectServlet, in your WEB-INF/web.xml...
<web-app ...>
<welcome-file-list>
<welcome-file>console/console.jsp</welcome-file>
</welcome-file-list>
... other entries
</web-app>
If that doesn't work, consider making that a RedirectFilter instead, and only sending a redirect if the request.getRequestURI() is only in a list of exact request URI string matches that should redirect.
I getting started with Java and rest services, i created a rest service with GET method, this method return a UserVO with his properties, im set properties values with random values using setMethods and return object but this not work mapping object to json of jersey. I using tomcat 6, JDK 1.8.0_121 and eclipse and show this error:
com.sun.jersey.spi.container.ContainerResponse write
GRAVE: A message body writer for Java class Autoconsulta.ValueObject.UsuarioVO, and Java type class Autoconsulta.ValueObject.UsuarioVO, and MIME media type application/json was not found.
The registered message body writers compatible with the MIME media type are:
application/json ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
VO
public class UsuarioVO {
private String rut;
private boolean isValid;
public String getRut() {
return rut;
}
public void setRut(String rut) {
this.rut = rut;
}
public boolean isValid() {
return isValid;
}
public void setValid(boolean isValid) {
this.isValid = isValid;
}
}
my ret service:
#GET
#Path("/getUser")
#Produces({MediaType.APPLICATION_JSON})
public UsuarioVO getUsuario() {
UsuarioVO u = new UsuarioVO();
u.setRut("123444");
u.setValid(true);
return u;
}
web xml
<servlet>
<servlet-name>Servicio_Rest</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>Autoconsulta.ws.rest.service</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Servicio_Rest</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
pom xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
I'm using Resteasy 3.0.11.Final with JBoss AS 5.1.0 GA. I have a defined REST web service. The whole service is secured with BASIC authentication with a custom security domain. When I use Postman to send a request (#1) with BASIC authentication for user A, JBoss AS invokes a login module for the user, and then calls a local ejb (looked up with initial context) method with caller principal A. Immidiately after I send another request (#2) with BASIC authentication for user B, in this case JBoss AS does not invoke a login module and calls a local ejb method with caller principal A again. After some time sending a request with user B yields the desired result (local ejb method call with caller principal B). I'm not sure what causes the problem, the Resteasy service configuration / session handling or the JBoss AS security domain configuration which is responsible for login modules (subject timeout? lack of logout after method being called?)? Basically I want to configure Resteasy to force a new session with a new login module invocation for the local ejb method call for every rest request.
web.xml:
<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>my-app</display-name>
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider,com.mycompany.infrastructure.ExceptionMapper</param-value>
</context-param>
<context-param>
<param-name>resteasy.resources</param-name>
<param-value>com.mycompany.resource.Resource</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<servlet-name>my-app-resteasy-servlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
<init-param>
<param-name>javax.ws.rs.core.Application</param-name>
<param-value>com.mycompany.application.Application</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>my-app-resteasy-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>my-app-resteasy-servlet</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>User</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>MyRealm</realm-name>
</login-config>
<security-role>
<role-name>User</role-name>
</security-role>
</web-app>
jboss-web.xml
<jboss-web>
<context-root>/path</context-root>
<security-domain>java:/jaas/MyRealm</security-domain>
</jboss-web>
beans.xml
<beans
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/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
login-config.xml for MyRealm
<application-policy name="MyRealm">
<authentication>
<login-module code="com.mycompany.security.UsernamePasswordLoginModuleImpl"
flag="required">
<module-option name="password-stacking">useFirstPass</module-option>
</login-module>
</authentication>
</application-policy>
Resource.java
#Path("/resource")
#Stateless
public class Resource {
#POST
#Path("/execute")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public ResponseDTO execute(RequestDTO dto) {
try {
// code
} catch (Exception exception) {
// handle
}
}
}
I found a very rough solution:
Resource.java:
#Path("/resource")
#Stateless
public class Resource {
#POST
#Path("/execute")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public ResponseDTO execute(RequestDTO dto, #Context HttpServletRequest request) {
try {
// code
} catch (Exception exception) {
// handle
} finally {
if (request != null) {
request.getSession().invalidate();
}
}
}
}
or the same result, different implementation (without repeating the same code in every method in a resource, obviously):
SessionInvalidatorFilter.java
public class SessionInvalidatorFilter implements ContainerResponseFilter {
#Context
private HttpServletRequest request;
public void filter(ContainerRequestContext requestCtx, ContainerResponseContext responseCtx) throws IOException {
if ((request != null) && (request.getSession() != null)) {
request.getSession().invalidate();
}
}
}
web.xml
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>com.mycompany.infrastructure.filter.SessionInvalidatorFilter</param-value>
</context-param>
I am just trying out a sample rest service example. My rest service class is :
#Path("oauth")
public class OauthClass {
private static Map<String, OauthBean> oAuthBeanMap = new HashMap<String, OauthBean>();
static {
OauthBean oAuthBean = new OauthBean();
oAuthBean.setAccess_token(String.valueOf(Math.random()));
oAuthBean.setToken_type("bearer");
oAuthBean.setRefresh_token(String.valueOf(Math.random()));
oAuthBean.setExpires_in("44517");
oAuthBeanMap.put(oAuthBean.getToken_type(), oAuthBean);
}
#GET
#Path("/token?client_id={clntID}")
#Produces("application/json")
public OauthBean getOAuthJSON(#PathParam("clntID") String clientID) {
System.out.println(clientID + " Secret ");
System.out.println("oAuthBeanMap.get(\"bearer\") :P " + oAuthBeanMap.get("bearer"));
return oAuthBeanMap.get("bearer");
}
}
Now when i trry to invoke this url :
http://localhost:7070/RESTfulWS/rest/oauth/token?client_id=clnt001
I get a 405 error.Method not allowed
Below is 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>RESTfulWS</display-name>
<servlet>
<servlet-name>Jersey REST Service</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.eviac.blog.restws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I am using jersey 1.18.
What am i doing wrong? Looking forward tyo your solutions.
Reading through your code, I think you should write #Path("/token") instead of #Path("/token?client_id={clntID}").
Besides, as you yourself noted, you should use QueryParam instead of PathParam
I'm following the tutorial here
http://jfarcand.wordpress.com/2011/06/29/rest-websocket-applications-why-not-using-the-atmosphere-framework/
I already have a Jersey project up and running and working fine using JBoss 7. The one difference i have is that i am using Jersey with Spring. So my JQueryPubSub looks like this
#Service <-- For Spring component Scan
#Path("/pubsub/{topic}")
#Produces("text/html;charset=ISO-8859-1")
public class JQueryPubSub {
#PathParam("topic")
Broadcaster topic;
#GET
public SuspendResponse<String> subscribe() {
return new SuspendResponse.SuspendResponseBuilder<String>()
.broadcaster(topic)
.outputComments(true)
.addListener(new EventsLogger())
.build();
}
#POST
#Broadcast
public Broadcastable publish(#FormParam("message") String message) {
return new Broadcastable(message, "", topic);
}
}
So i wanted to add this example but i'm getting
22:55:27,381 SEVERE [com.sun.jersey.spi.inject.Errors] (MSC service thread 1-3) The following errors and warnings have been detected with resource
and/or provider classes:
SEVERE: Missing dependency for field: org.atmosphere.cpr.Broadcaster com.order.resources.JQueryPubSub.topic
Any ideas how i can fix this issue and why Jersey seems to be aggressively injecting the value into broadcaster??
I had the same problem and was able to fix it by updating jersey jars from 1.4 to 1.6
If you use maven, you can add the following dependencies.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.6</version>
</dependency>
Answering after long time..but people who are trying can still take some advantage out of this
You can try with the following .
I just tried and it worked for me
Step-1
If you are using weblogic 12 c make the following change
function subscribe() {
var request = {
url :document.location.origin+'/<your-context-path>/ws/pubsub/' + getElementByIdValue('topic'),
Step-2
In web.xml add the below configuration
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>*******package name where your handler is**********</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
<param-value>org.atmosphere.client.TrackMessageSizeFilter
</param-value>
</init-param>
<init-param>
<param-name>WEBSOCKET_PROTOCOL_EXECUTION</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<url-pattern>/pubsub/*</url-pattern>
</servlet-mapping>
step-3
paste the below code in a java file in the package you defined in the above step(also can be found in the git site of atmosphere)
import java.io.IOException;
import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.config.service.AtmosphereHandlerService;
import org.atmosphere.config.service.Singleton;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.handler.AtmosphereHandlerAdapter;
import org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor;
import org.atmosphere.interceptor.BroadcastOnPostAtmosphereInterceptor;
import org.atmosphere.interceptor.SuspendTrackerInterceptor;
import org.atmosphere.util.SimpleBroadcaster;
#Singleton
#AtmosphereHandlerService(path = "/{chat}",
interceptors = {
AtmosphereResourceLifecycleInterceptor.class,
TrackMessageSizeInterceptor.class,
BroadcastOnPostAtmosphereInterceptor.class,
SuspendTrackerInterceptor.class},
broadcaster = SimpleBroadcaster.class)
public class AtmosphereHandler extends AtmosphereHandlerAdapter {
#Override
public void onStateChange(AtmosphereResourceEvent event) throws IOException {
if (event.isSuspended()) {
String message = event.getMessage() == null ? null : event.getMessage().toString();
if (message != null && message.indexOf("message") != -1) {
event.getResource().write(message.substring("message=".length()));
} else {
event.getResource().write("=error=");
}
}
}
}
Now deploy the ear it works..
Jar files
atmosphere-annotations-2.1.1.jar
atmosphere-jersey-2.1.1.jar
atmosphere-runtime-2.1.1.jar
atmosphere-weblogic-2.1.1.jar
commons-collections-3.2.1.jar
commons-dbutils-1.5.jar
commons-io-2.4.jar
jersey-core-1.17.1.jar
jersey-json-1.17.1.jar
jersey-server-1.17.1.jar
jersey-servlet-1.17.1.jar
log4j-1.2.15.jar