I am following the Atmosphere tutorial to get a basic chat application setup. Currently when running the javascript, it appears to be able to establish a connection to the server using web sockets. I get the following in the Chrome console:
Invoking executeWebSocket core.js:2298
Using URL: ws://localhost:8080/web-transport/chat?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=1.1&X-Atmosphere-Transport=websocket&X-Cache-Date=0&Content-Type=application/json core.js:2298
Websocket successfully opened
However, when I attempt to publish data (subSocket.push(...)) nothing seems to happen. I have tried debugging the AtmosphereHandlerService but it never seems to be hit (and no logs are being generated.
What am I missing that would cause this?
So far I have the following:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:j2ee="http://java.sun.com/xml/ns/javaee" 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.5.xsd">
<description>AtmosphereServlet</description>
<display-name>AtmosphereServlet</display-name>
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<!-- If you want to use Servlet 3.0 -->
<!-- <async-supported>true</async-supported> -->
<!-- List of init-param -->
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<!-- Any mapping -->
<url-pattern>/chat/*</url-pattern>
</servlet-mapping>
</web-app>
ChatAtmosphereHandler.java
#AtmosphereHandlerService(path = "/chat")
public class ChatAtmosphereHandler implements AtmosphereHandler {
public void onRequest(AtmosphereResource resource) throws IOException {
AtmosphereRequest request = resource.getRequest();
if (request.getMethod().equalsIgnoreCase("GET")) {
resource.suspend();
} else if (request.getMethod().equalsIgnoreCase("POST")) {
resource.getBroadcaster().broadcast(request.getReader().readLine().trim());
}
}
public void onStateChange(AtmosphereResourceEvent event) throws IOException {
AtmosphereResource resource = event.getResource();
AtmosphereResponse response = resource.getResponse();
if (resource.isSuspended()) {
response.getWriter().write("Hello");
switch (resource.transport()) {
case JSONP:
case LONG_POLLING:
event.getResource().resume();
break;
case WEBSOCKET:
case STREAMING:
response.getWriter().flush();
break;
}
} else if (!event.isResuming()) {
event.broadcaster().broadcast("bye bye");
}
}
public void destroy() {
}
}
Maven dependencies:
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-jersey</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>eu.infomas</groupId>
<artifactId>annotation-detector</artifactId>
<version>3.0.1</version>
</dependency>
and finally the javascript:
$(document).ready(function() {
var socket = $.atmosphere;
var subSocket = null;
var request = {
url: 'http://localhost:8080/web-transport/' + 'chat',
contentType : "application/json",
logLevel : 'debug',
transport : 'websocket' ,
fallbackTransport: 'long-polling'
};
request.onOpen = function(response) {
console.log('onopen', response);
};
request.onReconnect = function (request, response) {
console.log('onreconnect', request, response);
};
request.onMessage = function (response) {
console.log('onmessage', response);
};
request.onError = function(response) {
console.log('onerror', response);
};
$('#send').click(function(){
subSocket.push(JSON.stringify({ author: 'me', message: 'hello' }));
});
$('#subscribe').click(function(){
subSocket = socket.subscribe(request);
});
});
I finally figured out that the problem wasn't with the code or atmosphere, but with Glassfish.
The solution is to enable web sockets using the following command:
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.websockets-support-enabled=true
Make sure that you run the command using the command prompt. I previously enabled web sockets via the admin gui and somehow it seems to not have been applied correctly. After I ran the above command and tried the above code it worked fine.
Related
I am integrating Spring Security into my Spring MVC and Angular App.
Versions:
Spring Security: 4.1.5.RELEASE
Spring MVC: 4.2.0.RELEASE
Angular: 4
After integration, I see that browser is showing pop up for user name and password. Even after following changes, I am not able to get rid of the pop up and proceed further to my custom login form in angular.
To start with I am using http basic authentication mechanism.
For this created following SecurityConfig.java.
[Updated]
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// #formatter:on
auth.inMemoryAuthentication().withUser("user1").password("user1").roles("USER").and().withUser("user2")
.password("user2").roles("USER").and().withUser("admin").password("admin").roles("ADMIN");
// #formatter:off
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:on
http
.authorizeRequests().antMatchers("/index.html", "/", "/login", "*.*", "/*.bundle.*", "/*.ico")
.permitAll().anyRequest().authenticated().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// #formatter:off
}
}
For resource and path resolution, created following ServletContextConfiguration.java .
#Configuration
#EnableWebMvc
public class ServletContextConfiguration extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).ignoreAcceptHeader(true).useJaf(false)
.defaultContentType(MediaType.APPLICATION_JSON).mediaType("html",
MediaType.TEXT_HTML)
.mediaType("xml", MediaType.APPLICATION_XML).mediaType("json",
MediaType.APPLICATION_JSON);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean(name = "contentNegotiatingViewResolver")
public ViewResolver getContentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("/dist/").resourceChain(true)
.addResolver(new PathResourceResolver());
}
}
Following is my web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<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 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>/index.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- Spring Security -->
<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>
</web-app>
I am using weblogic server to deploy war file.
weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
<wls:context-root>/</wls:context-root>
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>org.slf4j.*</wls:package-name>
<wls:package-name>org.springframework.*</wls:package-name>
<wls:package-name>org.springframework.web.servlet.view.*</wls:package-name>
<wls:package-name>oracle.core.*</wls:package-name>
<wls:package-name>oracle.jdbc.*</wls:package-name>
<wls:package-name>oracle.net.*</wls:package-name>
<wls:package-name>oracle.sql.*</wls:package-name>
<wls:package-name>oracle.security.*</wls:package-name>
<wls:package-name>org.hibernate.*</wls:package-name>
<wls:package-name>com.fasterxml.*</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
Angular Changes:
In app.module.ts introduced http interceptor to inject http header X-Requested-With as suggested here.
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { RouterModule, Routes } from '#angular/router';
import { NgModule } from '#angular/core';
import { Injectable } from '#angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS
} from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import { AppComponent } from './app.component';
import { StoreComponent } from './components/store/store.component';
import { StoreService } from './services/store.service';
import { LoginComponent } from './components/login/login.component';
import { LogoutComponent } from './components/logout/logout.component';
#Injectable()
export class XhrInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
const xhr = req.clone({
headers: req.headers.set('X-Requested-With', 'XMLHttpRequest')
});
console.log(">>>>>>>>>>HttpRequest intercepted...");
return next.handle(xhr);
}
}
const appRoutes: Routes = [
{ path:'', pathMatch: 'full', redirectTo: 'login' },
{ path: 'login', component: LoginComponent},
{ path: 'logout', component: LogoutComponent },
{ path: 'store', component: StoreComponent }
]
#NgModule({
declarations: [
AppComponent,
StoreComponent,
LoginComponent,
LogoutComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(appRoutes)
],
providers: [ StoreService, { provide: HTTP_INTERCEPTORS, useClass: XhrInterceptor, multi: true } ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
By some reason, still I am able to see the default user name and password pop up from browser.
In web console, I don't see the X-Requested-With header. Also, I don't see my console log which should have been printed while http request is intercepted.
I think, request might not be reaching angular client and something wrong happened in server side.
What could be missing here?
Update:
As suggested, I have replaced http.basic() request with http.authorizeRequests(). Now, pop up is not displayed for /login request. But after once I try to submit user credentials in my custom login page by calling /authenticate, again I see the pop up :(
What could be missing here.
Please clarify.
Thanks.
this is due to http.httpBasic() in your config, it should be http.authorizeRequests()
You are still using spring security's http basic authentication, that is why is it showing basic authentication pop up, dont use it , use http.autherizeRequest() and using machers permit your login url.
And in routemodule define same path for login component. It will work.
I have downloaded a tutorial and modified it a little to suit my needs (added maven)
I was just wondering what makes the service start at a particular home page - when i run my service it defaults to the following
http://localhost:8080/RESTfulExample/WEB-INF/classes/com/ricki/test/JettyService.java
My web.xml looks as follows
<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">
<display-name>Restful Web Application</display-name>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.ricki.test</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>
</web-app>
My jetty service class looks like this
import com.google.common.util.concurrent.AbstractIdleService;
import java.lang.management.ManagementFactory;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
public class JettyService extends AbstractIdleService
{
private Server server;
#Override
protected void startUp() throws Exception
{
server = new Server(8080);
MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addBean(mbContainer);
Resource resource = Resource.newClassPathResource("/webapp");
WebAppContext context = new WebAppContext(resource.getURL().toExternalForm(), "/ricki-test/");
server.setHandler(context);
server.start();
}
#Override
protected void shutDown() throws Exception
{
try
{
server.stop();
server.join();
}
finally
{
server.destroy();
}
}
}
Any my rest class looks as follows
#Path("/hello")
public class HelloWorldService
{
private final Logger logger = Logger.getLogger(HelloWorldService.class);
#GET
#Path("/{param}")
public Response getMsg(#PathParam("param") String msg)
{
logger.info("Received message " + msg);
String output = "Hi : " + msg;
return Response.status(200).entity(output).build();
}
}
Ideall my homepage would be set to http://localhost:8080/RESTfulExample/ whcih displays my home page or in fact http://localhost:8080/RESTfulExample/rest/hello/ricki which allows me to interact with my service.
Thanks for your time.
There is no need to use a web.xml file if you don't want to. If you are using an embedded Jetty server, you can do the wireing to Jersey manually:
public static void main(String[] args) throws Exception {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
Server jettyServer = new Server(8080);
jettyServer.setHandler(context);
ServletHolder jerseyServlet = context.addServlet(
org.glassfish.jersey.servlet.ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
jerseyServlet.setInitParameter(
"jersey.config.server.provider.classnames",
EntryPoint.class.getCanonicalName());
try {
jettyServer.start();
jettyServer.join();
} finally {
jettyServer.destroy();
}
}
Example from: http://www.nikgrozev.org/2014/10/16/rest-with-embedded-jetty-and-jersey-in-a-single-jar-step-by-step/
You can also use the jersey-container-jetty-http dependency:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>2.23.1</version>
</dependency>
This allows you to do:
URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build();
ResourceConfig config = new ResourceConfig(MyResource.class);
Server server = JettyHttpContainerFactory.createServer(baseUri, config);
If you really want to use web.xml, you should access it in a different fashion:
Server server = new Server(8080);
String rootPath = SimplestServer.class.getClassLoader().getResource(".").toString();
WebAppContext webapp = new WebAppContext(rootPath + "../../src/main/webapp", "");
server.setHandler(webapp);
server.start();
server.join();
See also: Configure embedded jetty with web.xml?
At that point, it is easier to use the Jetty maven plugin, which bundles your war file and deploys it to a local Jetty server:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.6.v20151106</version>
<configuration>
<scanTargets>
<scanTarget>${project.basedir}/src/main</scanTarget>
<scanTarget>${project.basedir}/src/test</scanTarget>
</scanTargets>
<webAppConfig>
<contextPath>/${project.artifactId}-${project.version}</contextPath>
</webAppConfig>
<contextPath>${project.artifactId}</contextPath>
</configuration>
</plugin>
I created an AJAX web app that should send some data (POSITIONS) to my servlet that would create a text file in my server containing that data. The problem is I don't know whether it's working or not, and I don't know how the web.xml works and how to configure it for my app.
UPDATE:
I'm getting that CORS problem, but my webapp.html and my .war file are at my localhost.
Server: Apache Tomcat 7.0
Eclipse EE Mars
Thanks in advance.
P.S.: I posted the snippet below only for observation, but I can't use script because I don't own the businesses where the libraries are, if you want to see it check it on the link above this PostScript.
My AJAX
$(document).ready(function() {
var POSITIONS;
//var data is a dynamic JSON file that should be created in the backend.
var data = [{
label: 'node1',
id: 1,
children: [{
label: 'child1',
id: 2
}, {
label: 'child2',
id: 3
}]
}, {
label: 'node2',
id: 4,
children: [{
label: 'child3',
id: 5
}]
}];
$('#tree1').tree({
data: data,
autoOpen: true,
dragAndDrop: true
});
console.log($('#tree1').tree('toJson')); //This will give you the loading jqtree structure.
$('#tree1').bind(
'tree.move',
function(event) {
event.preventDefault();
// do the move first, and _then_ POST back.
event.move_info.do_move();
console.log($(this).tree('toJson')); //this will give you the latest tree.
POSITIONS = $(this).tree('toJson');
alert(POSITIONS);
$.post('http://sistema.agrosys.com.br/sistema/labs/CSS_HTML/', {
tree: $(this).tree('toJson')
});
alert("done"); //this will post the json of the latest tree structure.
}
);
var data = new FormData();
data.append("JqTree", POSITIONS);
alert('Sending: ' + POSITIONS);
$.ajax({
url: '/JqTree/Hello',
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false,
contentType: false,
success: function(response) {
alert("file has been successfully sent\n\n" + POSITIONS);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('ERRORS: ' + textStatus);
}
});
});
My Servlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Hello extends HttpServlet {
private static final long serialVersionUID = 1L;
public Hello() {}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out=response.getWriter();
out.print("<html><body>");
out.print("<h3>Hello Servlet</h3>");
out.print("</body></html>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String position = request.getParameter("JqTree");
PrintWriter writer = new PrintWriter("Positions.txt", "UTF-8");
writer.println(position);
writer.close();
}
}
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" xmlns:web="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>JqTree</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>
<description></description>
<display-name>Hello</display-name>
<servlet-name>Hello</servlet-name>
<servlet-class>Hello</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/Hello</url-pattern>
</servlet-mapping>
</web-app>
As per the screenshot, you opened the HTML page by a file:// URL. Of course you will hit the CORS wall as the ajax request is not fired on file:// URL, but on http://localhost URL.
Fix the file:// URL to be a fullworthy http://localhost URL too and never use file:// URLs for web resources. Move that source.html file into public web content of the project and open it via:
http://localhost/JqTree/source.html
I get the following exception when I execute the REST Client :
InboundJaxrsResponse{ClientResponse{method=GET, uri=http://localhost:8080/com.dcr.jersey.first/webapi/todo, status=406, reason=Not Acceptable}}
Exception in thread "main" javax.ws.rs.NotAcceptableException: HTTP 406 Not Acceptable
On web browser( when tomcat is running), the URL : http://localhost:8080/com.dcr.jersey.first/webapi/todo gives output
todo>
<description>This is my first todo - Description</description>
<summary>This is my first todo - Summary</summary>
</todo>
But running the client code throws the exception, what is the mapping that's missing here?, appreciate your guidance( included all code samples)
Here is the web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<!-- <param-value>com.dcr.jersey</param-value> -->
<!-- <param-value>com.dcr.jersey.first</param-value> -->
<param-value>com.dcr.jersey.jaxb.model</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
Here is the TodoResourceCliient executed:
package com.dcr.jersey.client;
import java.net.URI;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.jersey.client.ClientConfig;
public class TodoResourceCliient {
public static void main(String[] args) {
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client.target(getBaseURI());
System.out.println(target.path("webapi").path("todo").request()
.accept(MediaType.TEXT_PLAIN).get(Response.class)
.toString());
System.out.println(target.path("webapi").path("todo").request()
.accept(MediaType.TEXT_HTML).get(String.class));
System.out.println(target.path("webapi").path("todo").request()
.accept(MediaType.TEXT_XML).get(String.class));
System.out.println(target.path("webapi").path("todo").request()
.accept(MediaType.TEXT_PLAIN).get(String.class));
System.out.println(target.path("webapi").path("todo").request()
.accept(MediaType.APPLICATION_JSON).get(String.class));
}
private static URI getBaseURI() {
return UriBuilder.fromUri("http://localhost:8080/com.dcr.jersey.first").build();
}
}
TodoResource.java:
package com.dcr.jersey.jaxb.model;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("/todo")
public class TodoResource {
#GET
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Todo getXML() {
Todo todo = new Todo();
todo.setSummary("This is my first todo - Summary\n");
todo.setDescription("This is my first todo - Description\n");
return todo;
}
// This can be used to test the integration with the browser
#GET
#Produces({ MediaType.TEXT_XML,MediaType.TEXT_PLAIN,MediaType.TEXT_HTML})
public Todo getHTML() {
Todo todo = new Todo();
todo.setSummary("This is my first todo - Summary\n");
todo.setDescription("This is my first todo - Description\n");
return todo;
}
}
Todo.java:
package com.dcr.jersey.jaxb.model;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Todo {
private String summary;
private String description;
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Stacktrace from Console :
InboundJaxrsResponse{ClientResponse{method=GET, uri=http://localhost:8080/com.dcr.jersey.first/webapi/todo, status=500, reason=Internal Server Error}}
Exception in thread "main" javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1002)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:799)
at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:91)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:687)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:683)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:307)
at com.dcr.jersey.client.TodoResourceCliient.main(TodoResourceCliient.java:27)
Dependencies included from pom.xml: am I missing any dependencies ?
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- JSON support -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
</dependencies>
See Http Status Codes
406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.
The .accept(mediatype) is what set the Accept header for the request. You currently have five requests, each accepting a different type
MediaType.TEXT_PLAIN,MediaType.TEXT_HTML, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON
This is Content-Negotiation at work. The server side configuration of this is with the use of the #Produces (which goes in hand with the Accept header) and #Consumes(which goes in hand with the Content-Type header).
That being said, look at all your #Produces annotations. You currently only support the producing of media types
MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON
The missing ones are in bold above. Remove those, and given all else is correct, this should work for you.
Check your content type!
Setting to .accept(MediaType.TEXT_PLAIN) worked for me.
As correctly stated by peeskillet, your client calls with accept(MediaType.TEXT_PLAIN) and accept(MediaType.TEXT_HTML) will cause issues since your TodoResource methods do not specify these media types in the #Produces annotation.
Either
change your TodoResource class to support these media types
change your client code to remove the calls corresponding to these media types
This question already has answers here:
How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
(16 answers)
Closed 4 years ago.
I was able to make my app works again, following the advices of user2821894, but after trying to call a servlet tomcat 7 stopped working again!!
If i try to delete the code where i call my servlet my web app doesent' work!!
Once i have a problem with a servlet tomcat stops working.
I had problem launching my web project on eclipse. I had problem with Tomcat 7.
So i 'delete' tomcat 7 from eclipse and then i added it again (again tomcat 7).
now i have no problem launching my web project, but i have problem on my servlet.
For example i get error like
WebServlet cannot be resolved to a type
The attribute value is undefined for the annotation type
I added servlet-api 3.0.jar to my project but i still have these problems.
This is the code of my servlet
package Jeans;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
import com.sun.java.swing.plaf.windows.TMSchema.Part;
import javax.servlet.http.Part;
#WebServlet("/FileUploadDBServlet ")
//// i got an error here////////////////////////////
#MultipartConfig(maxFileSize = 16177215)
public class FileUploadDBServlet extends HttpServlet {
private String dbURL = "db";
private String dbUser = "dbuser";
private String dbPass = "dbpassword";
String messageMio = "da contorllare";
GestioneDB gestioneDB;
boolean connessione;
Connection conn;
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String giorno= request.getParameter("giorno");
String mese= request.getParameter("mese");
String anno= request.getParameter("anno");
String dataFormatoItaliano = giorno + "-" + mese + "-" + anno;
String titolo = request.getParameter("titolo");
String titoletto = request.getParameter("titoletto");
String testoMouse = request.getParameter("testoMouse");
String link = request.getParameter("link");
String data = dataFormatoItaliano;
String testo = request.getParameter("testo");
//// i got an error here////////////////////////////
Part filePart = request.getPart("immaginePrincipale");
String didascaliaImmaginePrincipale = request.getParameter("didascaliaImmaginePrincipale");
InputStream immaginePrincipale = null;
if (filePart != null) {
// obtains input stream of the upload file
immaginePrincipale = filePart.getInputStream();
}
String message = null;
try {
gestioneDB = new GestioneDB();
conn = gestioneDB.cn();
gestioneDB.inserimentoNews(titolo, titoletto, testoMouse, link, testo, data, immaginePrincipale, didascaliaImmaginePrincipale);
String sql = "INSERT INTO allegati_news (allegato,didascalia,tipo,id_news,immagine) values (?,?,?,?,?)";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, "firstName");
statement.setString(2, "lastName");
statement.setInt(3, 1);
statement.setInt(4,1);
if (immaginePrincipale != null) {
statement.setBlob(5, immaginePrincipale);
}
int row = statement.executeUpdate();
if (row > 0) {
message = "File salvato nel db";
}
} catch (SQLException ex) {
message = "ERROR: " + ex.getMessage();
ex.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
request.setAttribute("Message", gestioneDB.getInserimentoNewMessaggio());
getServletContext().getRequestDispatcher("/Message.jsp").forward(request, response);
}
}
}
This is my web.xml file
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>Jeans2</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>
<description></description>
<display-name>prova</display-name>
<servlet-name>prova</servlet-name>
<servlet-class>Jeans.prova</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>prova</servlet-name>
<url-pattern>/prova</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>FileUploadDBServlet</display-name>
<servlet-name>FileUploadDBServlet</servlet-name>
<servlet-class>Jeans.FileUploadDBServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileUploadDBServlet</servlet-name>
<url-pattern>/FileUploadDBServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>BlobDisplay</display-name>
<servlet-name>BlobDisplay</servlet-name>
<servlet-class>Jeans.BlobDisplay</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BlobDisplay</servlet-name>
<url-pattern>/BlobDisplay</url-pattern>
</servlet-mapping>
</web-app>
Try adding servlet-api.jar instead of servelt-api-3.0 jar.Stop the server. Refresh the project and then start the server and see. I think it should work. Make sure you are adding the servlet-api.jar from tomcat lib folder. Suppose your tomcat is in C:\Tomcat\lib.
In eclipse right click your project-properties-javabuildpath-add external jars and then select the servlet-api.jar from your tomcat folder
Right click on project ---> Properties ---> Java Build Path ---> Add
Library... ---> Server Runtime ---> Apache Tomcat ----> Finish.
A possible reason for this error is using a wrong version of Servlet API. #WebServlet annotation is supported by Servlet 3.0. You must change the version from possibly 2.5 to 3.0. To do this in eclipse, right click your project and open Properties. Select Project Facets from the left menu of the page shown. Then change the version of Dynamic Web Module facet to 3.0.
Another possible reason can be related to your Tomcat version. Tomcat is supporting Servlet 3.0 beggining from version 7.0.